diff --git a/packages/nitro-react/src/MainView.tsx b/packages/nitro-react/src/MainView.tsx index b1fefc4..0d0acb7 100644 --- a/packages/nitro-react/src/MainView.tsx +++ b/packages/nitro-react/src/MainView.tsx @@ -1,7 +1,7 @@ import { InfoRetrieveComposer } from "@nitrodevco/nitro-shared"; import { useEffect, useState } from "react"; -import { RoomWrapper } from "./components"; +import { NitroTooltip,RoomWrapper } from "./components"; import { useWebSocketContext } from "./context"; import { useNavigatorHandler, useUserInfoHandler } from "./handlers"; import { ToolbarView } from "./views/toolbar/ToolbarView"; @@ -39,6 +39,7 @@ export const MainView = () => { id="ui-container" className="absolute top-0 left-0 z-10 overflow-hidden pointer-events-none size-full [image-rendering:pixelated]"> + ); diff --git a/packages/nitro-react/src/assets/components.css b/packages/nitro-react/src/assets/components.css new file mode 100644 index 0000000..33b66f1 --- /dev/null +++ b/packages/nitro-react/src/assets/components.css @@ -0,0 +1,31 @@ +@layer components { + .nitro-tooltip { + position: fixed; + top: 0; + left: 0; + z-index: 1000; + max-width: 320px; + padding: 3px 6px; + border-radius: 10px; + background-color: rgb(0 0 0 / 0.8); + color: #fff; + font-size: 0.68rem; + line-height: 1.25; + overflow-wrap: anywhere; + + pointer-events: none; + + will-change: transform; + animation: nitro-tooltip-in 90ms ease-out; + } + + @keyframes nitro-tooltip-in { + from { + opacity: 0; + } + + to { + opacity: 1; + } + } +} diff --git a/packages/nitro-react/src/assets/icons.css b/packages/nitro-react/src/assets/icons.css index b5dcf90..d095511 100644 --- a/packages/nitro-react/src/assets/icons.css +++ b/packages/nitro-react/src/assets/icons.css @@ -1,5 +1,5 @@ .nitro-icon { - @apply inline-block outline-0 bg-transparent bg-no-repeat bg-center; + @apply outline-0 bg-transparent bg-no-repeat bg-center; &.icon-nitro-light { background-image: url('./flash/nitro/nitro-n-light.svg'); diff --git a/packages/nitro-react/src/components/AutoGrid.tsx b/packages/nitro-react/src/components/AutoGrid.tsx new file mode 100644 index 0000000..8165ac7 --- /dev/null +++ b/packages/nitro-react/src/components/AutoGrid.tsx @@ -0,0 +1,34 @@ +import { forwardRef } from 'react'; + +import { Grid, type GridProps } from './Grid'; + +export interface AutoGridProps extends Omit { + columnMinWidth?: number; + columnMinHeight?: number; +} + +export const AutoGrid = forwardRef( + ({ + columnMinWidth = 40, + columnMinHeight = 40, + maxContent = true, + overflow = 'auto', + style, + ...props + }, ref) => ( + + ) +); + +AutoGrid.displayName = 'AutoGrid'; diff --git a/packages/nitro-react/src/components/Base.tsx b/packages/nitro-react/src/components/Base.tsx new file mode 100644 index 0000000..46c45c5 --- /dev/null +++ b/packages/nitro-react/src/components/Base.tsx @@ -0,0 +1,105 @@ +import { forwardRef,type HTMLAttributes } from 'react'; + +import { cn, cva } from '#base/utils'; +import { CursorType, DisplayType, FlexGrowType, FlexShrinkType, OverflowType, PositionType, TextColorType } from '#base/utils/styles'; + +import { DEFAULT_TOOLTIP_ID, type NitroTooltipFollowType, type NitroTooltipPlacementType } from './NitroTooltip'; + +const baseVariants = cva( + '', + { + variants: { + display: DisplayType, + grow: FlexGrowType, + shrink: FlexShrinkType, + overflow: OverflowType.all, + position: PositionType, + cursor: CursorType, + textColor: TextColorType + } + } +); + +type BaseVariantProps = NonNullable[0]>; + +interface TooltipProps { + tooltipId?: string; + tooltipContent?: string; + tooltipFollow?: NitroTooltipFollowType; + tooltipPlacement?: NitroTooltipPlacementType; + tooltipDelay?: number; + tooltipFixed?: boolean; + tooltipClassName?: string; +} + +const tooltipAttributes = ({ tooltipId, tooltipContent, tooltipFollow, tooltipPlacement, tooltipDelay, tooltipFixed, tooltipClassName }: TooltipProps) => { + if ((tooltipContent == null) && (tooltipId == null)) return null; + + return { + 'data-tooltip-id': tooltipId ?? DEFAULT_TOOLTIP_ID, + 'data-tooltip-content': tooltipContent, + 'data-tooltip-follow': (tooltipFollow == null) ? undefined : String(tooltipFollow), + 'data-tooltip-placement': tooltipPlacement, + 'data-tooltip-delay': (tooltipDelay == null) ? undefined : String(tooltipDelay), + 'data-tooltip-fixed': tooltipFixed ? '' : undefined, + 'data-tooltip-class': tooltipClassName + }; +}; + +export interface BaseProps extends HTMLAttributes, Omit, TooltipProps { + className?: string; + fit?: boolean; + fullWidth?: boolean; + fullHeight?: boolean; + visible?: boolean; +} + +export const Base = forwardRef( + ({ + className, + fit, + fullWidth, + fullHeight, + visible, + display, + grow, + shrink, + overflow, + position, + cursor, + textColor, + tooltipId, + tooltipContent, + tooltipFollow, + tooltipPlacement, + tooltipDelay, + tooltipFixed, + tooltipClassName, + ...props + }, ref) => ( +
+ ) +); + +Base.displayName = 'Base'; diff --git a/packages/nitro-react/src/components/Column.tsx b/packages/nitro-react/src/components/Column.tsx new file mode 100644 index 0000000..5080230 --- /dev/null +++ b/packages/nitro-react/src/components/Column.tsx @@ -0,0 +1,16 @@ +import { forwardRef } from 'react'; + +import { Flex, type FlexProps } from './Flex'; + +export type ColumnProps = Omit; + +export const Column = forwardRef( + ({ + gap = 2, + ...props + }, ref) => ( + + ) +); + +Column.displayName = 'Column'; diff --git a/packages/nitro-react/src/components/Flex.tsx b/packages/nitro-react/src/components/Flex.tsx new file mode 100644 index 0000000..254ef5e --- /dev/null +++ b/packages/nitro-react/src/components/Flex.tsx @@ -0,0 +1,110 @@ +import { forwardRef } from 'react'; + +import { cn, cva } from '#base/utils'; +import { AlignContentType, AlignItemsType, AlignSelfType, DisplayType, FlexDirectionType, FlexGrowType, FlexShrinkType, FlexType, FlexWrapType, GapType, JustifyContentType, JustifySelfType, OverflowType, PositionType } from '#base/utils/styles'; + +import { Base, type BaseProps } from './Base'; + +const flexVariants = cva( + '', + { + variants: { + display: DisplayType, + direction: FlexDirectionType, + justify: JustifyContentType, + align: AlignItemsType, + alignContent: AlignContentType, + alignSelf: AlignSelfType, + justifySelf: JustifySelfType, + wrap: FlexWrapType, + flex: FlexType, + grow: FlexGrowType, + shrink: FlexShrinkType, + gap: GapType.all, + gapX: GapType.x, + gapY: GapType.y, + overflow: OverflowType.all, + overflowX: OverflowType.x, + overflowY: OverflowType.y, + position: PositionType + }, + defaultVariants: { + display: 'flex', + gap: 2 + } + } +); + +type FlexVariantProps = NonNullable[0]>; + +export interface FlexProps extends Omit, Omit { + column?: boolean; + reverse?: boolean; + center?: boolean; + inline?: boolean; +} + +export const Flex = forwardRef( + ({ + className, + column, + reverse, + center, + inline, + direction, + justify, + align, + alignContent, + alignSelf, + justifySelf, + wrap, + flex, + grow, + shrink, + gap, + gapX, + gapY, + overflow, + overflowX, + overflowY, + position, + ...props + }, ref) => { + const resolvedDirection = direction ?? (column + ? (reverse ? 'colReverse' : 'col') + : (reverse ? 'rowReverse' : undefined) + ); + + return ( + + ); + } +); + +Flex.displayName = 'Flex'; diff --git a/packages/nitro-react/src/components/Grid.tsx b/packages/nitro-react/src/components/Grid.tsx new file mode 100644 index 0000000..8f4b6ba --- /dev/null +++ b/packages/nitro-react/src/components/Grid.tsx @@ -0,0 +1,109 @@ +import { forwardRef } from 'react'; + +import { cn, cva } from '#base/utils'; +import { AlignContentType, AlignItemsType, AlignSelfType, DisplayType, GapType, GridColSpanType, GridColStartType, GridColumnsType, GridFlowType, GridRowSpanType, GridRowsType, JustifyContentType, JustifyItemsType, JustifySelfType, OverflowType, PositionType } from '#base/utils/styles'; + +import { Base, type BaseProps } from './Base'; + +const gridVariants = cva( + '', + { + variants: { + display: DisplayType, + columns: GridColumnsType, + rows: GridRowsType, + colSpan: GridColSpanType, + colStart: GridColStartType, + rowSpan: GridRowSpanType, + flow: GridFlowType, + justify: JustifyContentType, + justifyItems: JustifyItemsType, + justifySelf: JustifySelfType, + align: AlignItemsType, + alignContent: AlignContentType, + alignSelf: AlignSelfType, + gap: GapType.all, + gapX: GapType.x, + gapY: GapType.y, + overflow: OverflowType.all, + overflowX: OverflowType.x, + overflowY: OverflowType.y, + position: PositionType + }, + defaultVariants: { + display: 'grid', + columns: 12, + gap: 2 + } + } +); + +type GridVariantProps = NonNullable[0]>; + +export interface GridProps extends Omit, Omit { + center?: boolean; + inline?: boolean; + maxContent?: boolean; +} + +export const Grid = forwardRef( + ({ + className, + center, + inline, + maxContent, + columns, + rows, + colSpan, + colStart, + rowSpan, + flow, + justify, + justifyItems, + justifySelf, + align, + alignContent, + alignSelf, + gap, + gapX, + gapY, + overflow, + overflowX, + overflowY, + position, + ...props + }, ref) => ( + + ) +); + +Grid.displayName = 'Grid'; diff --git a/packages/nitro-react/src/components/NitroIcon.tsx b/packages/nitro-react/src/components/NitroIcon.tsx index d853b78..046ba7b 100644 --- a/packages/nitro-react/src/components/NitroIcon.tsx +++ b/packages/nitro-react/src/components/NitroIcon.tsx @@ -1,15 +1,17 @@ -import { forwardRef, HTMLAttributes } from 'react'; +import { forwardRef } from 'react'; import { cn } from '#base/utils'; -interface NitroIconProps extends HTMLAttributes { - className?: string; +import { Base, type BaseProps } from './Base'; + +interface NitroIconProps extends BaseProps { icon: string; } export const NitroIcon = forwardRef( ({ className, icon, ...props }, ref) => ( -
( ) ); -NitroIcon.displayName = 'NitroIcon'; \ No newline at end of file +NitroIcon.displayName = 'NitroIcon'; diff --git a/packages/nitro-react/src/components/NitroTooltip.tsx b/packages/nitro-react/src/components/NitroTooltip.tsx new file mode 100644 index 0000000..74a412d --- /dev/null +++ b/packages/nitro-react/src/components/NitroTooltip.tsx @@ -0,0 +1,324 @@ +import { type ReactNode, useCallback, useEffect, useLayoutEffect, useRef, useState } from 'react'; +import { createPortal } from 'react-dom'; + +import { cn, extractNumber } from '#base/utils'; + +export type NitroTooltipFollowType = boolean | 'x' | 'y'; + +export type NitroTooltipPlacementType = 'top' | 'top-left' | 'top-right' | 'left' | 'right' | 'bottom' | 'bottom-left' | 'bottom-right'; + +type TooltipSideType = 'top' | 'bottom' | 'left' | 'right'; + +type TooltipAlignType = 'left' | 'right'; + +interface TooltipBounds { + left: number; + right: number; + top: number; + bottom: number; +} + +interface TooltipSize { + width: number; + height: number; +} + +export const DEFAULT_TOOLTIP_ID = 'nitro-tooltip'; + +const PLACEMENTS: NitroTooltipPlacementType[] = ['top', 'top-left', 'top-right', 'left', 'right', 'bottom', 'bottom-left', 'bottom-right']; + +export interface NitroTooltipRenderProps { + anchor: HTMLElement; + content: string | null; +} + +export interface NitroTooltipProps { + id?: string; + follow?: NitroTooltipFollowType; + placement?: NitroTooltipPlacementType; + delay?: number; + offset?: number; + className?: string; + container?: Element | null; + render?: (props: NitroTooltipRenderProps) => ReactNode; +} + +export const NitroTooltip = ({ id = DEFAULT_TOOLTIP_ID, follow = true, placement = 'bottom-left', delay = 0, offset = 12, className, container, render }: NitroTooltipProps) => { + const VIEWPORT_MARGIN = 1; + const VERIFY_INTERVAL = 150; + const CURSOR_RADIUS = 3; + + const [anchor, setAnchor] = useState(null); + const [content, setContent] = useState(null); + const [pinned, setPinned] = useState(false); + + const timerRef = useRef(0); + const pointRef = useRef({ x: 0, y: 0 }); + const tooltipRef = useRef(null); + + const selector = `[data-tooltip-id="${id}"]`; + + const close = useCallback(() => { + window.clearTimeout(timerRef.current); + + setAnchor(null); + setContent(null); + setPinned(false); + }, []); + + const show = useCallback((element: HTMLElement) => { + setAnchor(element); + setContent(element.dataset.tooltipContent ?? null); + }, []); + + const anchorAt = useCallback((x: number, y: number) => { + const element = document.elementFromPoint(x, y); + + return (element instanceof Element) ? element.closest(selector) : null; + }, [selector]); + + const resolveFollowProperty = (value: string | undefined, fallback: NitroTooltipFollowType): NitroTooltipFollowType => { + if ((value === 'x') || (value === 'y')) return value; + if (value === 'true') return true; + if (value === 'false') return false; + + return fallback; + }; + + const resolvePlacementProperty = (value: string | undefined, fallback: NitroTooltipPlacementType): NitroTooltipPlacementType => { + return PLACEMENTS.includes(value as NitroTooltipPlacementType) ? value as NitroTooltipPlacementType : fallback; + } + + const clamp = (value: number, size: number, viewport: number) => { + return Math.min(Math.max(VIEWPORT_MARGIN, value), viewport - size - VIEWPORT_MARGIN); + } + + const calculateElementPosition = (placement: NitroTooltipPlacementType, reference: TooltipBounds, size: TooltipSize, offset: number, clearance: { x: number, y: number }) => { + const [side, align] = placement.split('-') as [TooltipSideType, TooltipAlignType?]; + + const beforeX = reference.left - clearance.x - size.width - offset; + const afterX = reference.right + clearance.x + offset; + const beforeY = reference.top - clearance.y - size.height - offset; + const afterY = reference.bottom + clearance.y + offset; + + if ((side === 'left') || (side === 'right')) { + const x = (side === 'left') ? beforeX : afterX; + + const fits = (side === 'left') + ? (x >= VIEWPORT_MARGIN) + : ((x + size.width) <= (window.innerWidth - VIEWPORT_MARGIN)); + + return { + x: fits ? x : ((side === 'left') ? afterX : beforeX), + y: (reference.top + reference.bottom - size.height) / 2 + }; + } + + const y = (side === 'top') ? beforeY : afterY; + + const fits = (side === 'top') + ? (y >= VIEWPORT_MARGIN) + : ((y + size.height) <= (window.innerHeight - VIEWPORT_MARGIN)); + + let alignedX = reference.left + clearance.x; + + if(align !== 'left') { + alignedX = align === 'right' + ? reference.right - clearance.x - size.width + : (reference.left + reference.right - size.width) / 2; + } + + return { + x: alignedX, + y: fits ? y : ((side === 'top') ? afterY : beforeY) + }; + }; + + const place = useCallback(() => { + const node = tooltipRef.current; + + if (!anchor || !node) return; + + const rect = anchor.getBoundingClientRect(); + const size = node.getBoundingClientRect(); + + const point = pointRef.current; + const activeFollow = resolveFollowProperty(anchor.dataset.tooltipFollow, follow); + const activePlacement = resolvePlacementProperty(anchor.dataset.tooltipPlacement, placement); + + const followX = !pinned && ((activeFollow === true) || (activeFollow === 'x')); + const followY = !pinned && ((activeFollow === true) || (activeFollow === 'y')); + + const reference: TooltipBounds = { + left: followX ? point.x : rect.left, + right: followX ? point.x : rect.right, + top: followY ? point.y : rect.top, + bottom: followY ? point.y : rect.bottom + }; + + const clearance = { + x: followX ? CURSOR_RADIUS : 0, + y: followY ? CURSOR_RADIUS : 0 + }; + + const { x, y } = calculateElementPosition(activePlacement, reference, size, offset, clearance); + + node.style.transform = `translate3d(${Math.round(clamp(x, size.width, window.innerWidth))}px, ${Math.round(clamp(y, size.height, window.innerHeight))}px, 0)`; + }, [anchor, pinned, follow, placement, offset]); + + useEffect(() => { + const onPointerOver = (event: PointerEvent) => { + if (pinned) return; + + const target = event.target; + const element = (target instanceof Element) ? target.closest(selector) : null; + + if (!element || (element === anchor)) return; + + pointRef.current = { x: event.clientX, y: event.clientY }; + + window.clearTimeout(timerRef.current); + + const wait = anchor ? 0 : extractNumber(element.dataset.tooltipDelay, delay); + + if (wait <= 0) { + show(element); + return; + } + + timerRef.current = window.setTimeout(() => { + if (anchorAt(pointRef.current.x, pointRef.current.y) !== element) return; + + show(element); + }, wait); + }; + + document.addEventListener('pointerover', onPointerOver, true); + + return () => document.removeEventListener('pointerover', onPointerOver, true); + }, [selector, anchor, pinned, delay, show, anchorAt]); + + useEffect(() => { + const onPointerDown = (event: PointerEvent) => { + const target = event.target; + const element = (target instanceof Element) ? target.closest(selector) : null; + + if (pinned) { + if (tooltipRef.current?.contains(target as Node)) return; + if (element && (element !== anchor)) return; + + close(); + + return; + } + + if (!element || (element.dataset.tooltipFixed == null)) return; + + pointRef.current = { x: event.clientX, y: event.clientY }; + + window.clearTimeout(timerRef.current); + + show(element); + setPinned(true); + }; + + const onKeyDown = (event: KeyboardEvent) => { + if (event.key === 'Escape') close(); + }; + + document.addEventListener('pointerdown', onPointerDown, true); + document.addEventListener('keydown', onKeyDown); + + return () => { + document.removeEventListener('pointerdown', onPointerDown, true); + document.removeEventListener('keydown', onKeyDown); + }; + }, [selector, anchor, pinned, close, show]); + + useEffect(() => { + const track = (event: PointerEvent) => { + pointRef.current = { x: event.clientX, y: event.clientY }; + }; + + document.addEventListener('pointermove', track, true); + + return () => document.removeEventListener('pointermove', track, true); + }, []); + + useLayoutEffect(() => { + if (anchor) place(); + }, [anchor, content, place]); + + useEffect(() => { + if (!anchor) return; + + const update = () => { + if (!anchor.isConnected) return close(); + + const rect = anchor.getBoundingClientRect(); + + if (!rect.width || !rect.height) return close(); + + if (!pinned) { + const { x, y } = pointRef.current; + const found = anchorAt(x, y); + + if (found !== anchor) { + if (found) show(found); + else close(); + + return; + } + + const next = anchor.dataset.tooltipContent ?? null; + + setContent(previous => (previous === next) ? previous : next); + } + + place(); + }; + + const onVisibility = () => { + if (document.hidden) close(); + }; + + const interval = window.setInterval(update, VERIFY_INTERVAL); + + document.addEventListener('pointermove', update, true); + document.documentElement.addEventListener('pointerleave', close); + document.addEventListener('visibilitychange', onVisibility); + + window.addEventListener('scroll', update, true); + window.addEventListener('resize', update); + window.addEventListener('blur', close); + + return () => { + window.clearInterval(interval); + + document.removeEventListener('pointermove', update, true); + document.documentElement.removeEventListener('pointerleave', close); + document.removeEventListener('visibilitychange', onVisibility); + + window.removeEventListener('scroll', update, true); + window.removeEventListener('resize', update); + window.removeEventListener('blur', close); + }; + }, [anchor, pinned, place, anchorAt, close, show]); + + useEffect(() => () => window.clearTimeout(timerRef.current), []); + + const target = container ?? document.getElementById('ui-container') ?? document.body; + const body = anchor ? (render ? render({ anchor, content }) : content) : null; + + if (!anchor || !target || (body == null) || (body === '')) return null; + + const tooltip = ( +
+ {body} +
+ ); + + return createPortal(tooltip, target); +}; diff --git a/packages/nitro-react/src/components/index.ts b/packages/nitro-react/src/components/index.ts index d37d4bb..32432f7 100644 --- a/packages/nitro-react/src/components/index.ts +++ b/packages/nitro-react/src/components/index.ts @@ -1,7 +1,13 @@ +export * from './AutoGrid'; export * from './AvatarImage'; +export * from './Base'; export * from './Button'; +export * from './Column'; +export * from './Flex'; export * from './FurnitureImage'; +export * from './Grid'; export * from './NitroIcon'; +export * from './NitroTooltip'; export * from './room/RoomCanvas'; export * from './room/RoomContainer'; export * from './room/RoomEventHandler'; diff --git a/packages/nitro-react/src/index.css b/packages/nitro-react/src/index.css index 0228e3d..bc6bd4a 100644 --- a/packages/nitro-react/src/index.css +++ b/packages/nitro-react/src/index.css @@ -4,4 +4,5 @@ @import './theme.css'; @import './assets/fonts.css'; @import './assets/utilities.css'; +@import './assets/components.css'; @import './assets/icons.css'; diff --git a/packages/nitro-react/src/utils/styles/AlignContentType.ts b/packages/nitro-react/src/utils/styles/AlignContentType.ts new file mode 100644 index 0000000..79e4b02 --- /dev/null +++ b/packages/nitro-react/src/utils/styles/AlignContentType.ts @@ -0,0 +1,12 @@ +export const AlignContentType = { + start: 'content-start', + end: 'content-end', + center: 'content-center', + between: 'content-between', + around: 'content-around', + evenly: 'content-evenly', + stretch: 'content-stretch', + baseline: 'content-baseline' +}; + +export type AlignContentType = keyof typeof AlignContentType; diff --git a/packages/nitro-react/src/utils/styles/AlignItemsType.ts b/packages/nitro-react/src/utils/styles/AlignItemsType.ts new file mode 100644 index 0000000..9a99aff --- /dev/null +++ b/packages/nitro-react/src/utils/styles/AlignItemsType.ts @@ -0,0 +1,9 @@ +export const AlignItemsType = { + start: 'items-start', + end: 'items-end', + center: 'items-center', + baseline: 'items-baseline', + stretch: 'items-stretch' +}; + +export type AlignItemsType = keyof typeof AlignItemsType; diff --git a/packages/nitro-react/src/utils/styles/AlignSelfType.ts b/packages/nitro-react/src/utils/styles/AlignSelfType.ts new file mode 100644 index 0000000..3c278fe --- /dev/null +++ b/packages/nitro-react/src/utils/styles/AlignSelfType.ts @@ -0,0 +1,10 @@ +export const AlignSelfType = { + auto: 'self-auto', + start: 'self-start', + end: 'self-end', + center: 'self-center', + baseline: 'self-baseline', + stretch: 'self-stretch' +}; + +export type AlignSelfType = keyof typeof AlignSelfType; diff --git a/packages/nitro-react/src/utils/styles/CursorType.ts b/packages/nitro-react/src/utils/styles/CursorType.ts new file mode 100644 index 0000000..3129b3b --- /dev/null +++ b/packages/nitro-react/src/utils/styles/CursorType.ts @@ -0,0 +1,15 @@ +export const CursorType = { + auto: 'cursor-auto', + default: 'cursor-default', + pointer: 'cursor-pointer', + text: 'cursor-text', + move: 'cursor-move', + grab: 'cursor-grab', + grabbing: 'cursor-grabbing', + wait: 'cursor-wait', + help: 'cursor-help', + notAllowed: 'cursor-not-allowed', + none: 'cursor-none' +}; + +export type CursorType = keyof typeof CursorType; diff --git a/packages/nitro-react/src/utils/styles/DisplayType.ts b/packages/nitro-react/src/utils/styles/DisplayType.ts new file mode 100644 index 0000000..46bc388 --- /dev/null +++ b/packages/nitro-react/src/utils/styles/DisplayType.ts @@ -0,0 +1,13 @@ +export const DisplayType = { + block: 'block', + inlineBlock: 'inline-block', + inline: 'inline', + flex: 'flex', + inlineFlex: 'inline-flex', + grid: 'grid', + inlineGrid: 'inline-grid', + contents: 'contents', + none: 'hidden' +}; + +export type DisplayType = keyof typeof DisplayType; diff --git a/packages/nitro-react/src/utils/styles/FlexDirectionType.ts b/packages/nitro-react/src/utils/styles/FlexDirectionType.ts new file mode 100644 index 0000000..f20a7f9 --- /dev/null +++ b/packages/nitro-react/src/utils/styles/FlexDirectionType.ts @@ -0,0 +1,8 @@ +export const FlexDirectionType = { + row: 'flex-row', + rowReverse: 'flex-row-reverse', + col: 'flex-col', + colReverse: 'flex-col-reverse' +}; + +export type FlexDirectionType = keyof typeof FlexDirectionType; diff --git a/packages/nitro-react/src/utils/styles/FlexGrowType.ts b/packages/nitro-react/src/utils/styles/FlexGrowType.ts new file mode 100644 index 0000000..43157aa --- /dev/null +++ b/packages/nitro-react/src/utils/styles/FlexGrowType.ts @@ -0,0 +1,6 @@ +export const FlexGrowType = { + 0: 'grow-0', + 1: 'grow' +}; + +export type FlexGrowType = keyof typeof FlexGrowType; diff --git a/packages/nitro-react/src/utils/styles/FlexShrinkType.ts b/packages/nitro-react/src/utils/styles/FlexShrinkType.ts new file mode 100644 index 0000000..eafc1c4 --- /dev/null +++ b/packages/nitro-react/src/utils/styles/FlexShrinkType.ts @@ -0,0 +1,6 @@ +export const FlexShrinkType = { + 0: 'shrink-0', + 1: 'shrink' +}; + +export type FlexShrinkType = keyof typeof FlexShrinkType; diff --git a/packages/nitro-react/src/utils/styles/FlexType.ts b/packages/nitro-react/src/utils/styles/FlexType.ts new file mode 100644 index 0000000..c24b448 --- /dev/null +++ b/packages/nitro-react/src/utils/styles/FlexType.ts @@ -0,0 +1,8 @@ +export const FlexType = { + 1: 'flex-1', + auto: 'flex-auto', + initial: 'flex-initial', + none: 'flex-none' +}; + +export type FlexType = keyof typeof FlexType; diff --git a/packages/nitro-react/src/utils/styles/FlexWrapType.ts b/packages/nitro-react/src/utils/styles/FlexWrapType.ts new file mode 100644 index 0000000..edae7bb --- /dev/null +++ b/packages/nitro-react/src/utils/styles/FlexWrapType.ts @@ -0,0 +1,7 @@ +export const FlexWrapType = { + wrap: 'flex-wrap', + reverse: 'flex-wrap-reverse', + no: 'flex-nowrap' +}; + +export type FlexWrapType = keyof typeof FlexWrapType; diff --git a/packages/nitro-react/src/utils/styles/GapType.ts b/packages/nitro-react/src/utils/styles/GapType.ts new file mode 100644 index 0000000..9c50c82 --- /dev/null +++ b/packages/nitro-react/src/utils/styles/GapType.ts @@ -0,0 +1,52 @@ +export const GapType = { + all: { + 0: 'gap-0', + 1: 'gap-1', + 2: 'gap-2', + 3: 'gap-3', + 4: 'gap-4', + 5: 'gap-5', + 6: 'gap-6', + 7: 'gap-7', + 8: 'gap-8', + 10: 'gap-10', + 12: 'gap-12', + 16: 'gap-16', + 20: 'gap-20', + 24: 'gap-24' + }, + x: { + 0: 'gap-x-0', + 1: 'gap-x-1', + 2: 'gap-x-2', + 3: 'gap-x-3', + 4: 'gap-x-4', + 5: 'gap-x-5', + 6: 'gap-x-6', + 7: 'gap-x-7', + 8: 'gap-x-8', + 10: 'gap-x-10', + 12: 'gap-x-12', + 16: 'gap-x-16', + 20: 'gap-x-20', + 24: 'gap-x-24' + }, + y: { + 0: 'gap-y-0', + 1: 'gap-y-1', + 2: 'gap-y-2', + 3: 'gap-y-3', + 4: 'gap-y-4', + 5: 'gap-y-5', + 6: 'gap-y-6', + 7: 'gap-y-7', + 8: 'gap-y-8', + 10: 'gap-y-10', + 12: 'gap-y-12', + 16: 'gap-y-16', + 20: 'gap-y-20', + 24: 'gap-y-24' + } +}; + +export type GapType = keyof typeof GapType.all; diff --git a/packages/nitro-react/src/utils/styles/GridColSpanType.ts b/packages/nitro-react/src/utils/styles/GridColSpanType.ts new file mode 100644 index 0000000..e26f58c --- /dev/null +++ b/packages/nitro-react/src/utils/styles/GridColSpanType.ts @@ -0,0 +1,18 @@ +export const GridColSpanType = { + 1: 'col-span-1', + 2: 'col-span-2', + 3: 'col-span-3', + 4: 'col-span-4', + 5: 'col-span-5', + 6: 'col-span-6', + 7: 'col-span-7', + 8: 'col-span-8', + 9: 'col-span-9', + 10: 'col-span-10', + 11: 'col-span-11', + 12: 'col-span-12', + full: 'col-span-full', + auto: 'col-auto' +}; + +export type GridColSpanType = keyof typeof GridColSpanType; diff --git a/packages/nitro-react/src/utils/styles/GridColStartType.ts b/packages/nitro-react/src/utils/styles/GridColStartType.ts new file mode 100644 index 0000000..f886b4d --- /dev/null +++ b/packages/nitro-react/src/utils/styles/GridColStartType.ts @@ -0,0 +1,17 @@ +export const GridColStartType = { + 1: 'col-start-1', + 2: 'col-start-2', + 3: 'col-start-3', + 4: 'col-start-4', + 5: 'col-start-5', + 6: 'col-start-6', + 7: 'col-start-7', + 8: 'col-start-8', + 9: 'col-start-9', + 10: 'col-start-10', + 11: 'col-start-11', + 12: 'col-start-12', + auto: 'col-start-auto' +}; + +export type GridColStartType = keyof typeof GridColStartType; diff --git a/packages/nitro-react/src/utils/styles/GridColumnsType.ts b/packages/nitro-react/src/utils/styles/GridColumnsType.ts new file mode 100644 index 0000000..a7ccd1b --- /dev/null +++ b/packages/nitro-react/src/utils/styles/GridColumnsType.ts @@ -0,0 +1,18 @@ +export const GridColumnsType = { + 1: 'grid-cols-1', + 2: 'grid-cols-2', + 3: 'grid-cols-3', + 4: 'grid-cols-4', + 5: 'grid-cols-5', + 6: 'grid-cols-6', + 7: 'grid-cols-7', + 8: 'grid-cols-8', + 9: 'grid-cols-9', + 10: 'grid-cols-10', + 11: 'grid-cols-11', + 12: 'grid-cols-12', + none: 'grid-cols-none', + subgrid: 'grid-cols-subgrid' +}; + +export type GridColumnsType = keyof typeof GridColumnsType; diff --git a/packages/nitro-react/src/utils/styles/GridFlowType.ts b/packages/nitro-react/src/utils/styles/GridFlowType.ts new file mode 100644 index 0000000..2ee18c8 --- /dev/null +++ b/packages/nitro-react/src/utils/styles/GridFlowType.ts @@ -0,0 +1,9 @@ +export const GridFlowType = { + row: 'grid-flow-row', + col: 'grid-flow-col', + dense: 'grid-flow-dense', + rowDense: 'grid-flow-row-dense', + colDense: 'grid-flow-col-dense' +}; + +export type GridFlowType = keyof typeof GridFlowType; diff --git a/packages/nitro-react/src/utils/styles/GridRowSpanType.ts b/packages/nitro-react/src/utils/styles/GridRowSpanType.ts new file mode 100644 index 0000000..7aef5ca --- /dev/null +++ b/packages/nitro-react/src/utils/styles/GridRowSpanType.ts @@ -0,0 +1,18 @@ +export const GridRowSpanType = { + 1: 'row-span-1', + 2: 'row-span-2', + 3: 'row-span-3', + 4: 'row-span-4', + 5: 'row-span-5', + 6: 'row-span-6', + 7: 'row-span-7', + 8: 'row-span-8', + 9: 'row-span-9', + 10: 'row-span-10', + 11: 'row-span-11', + 12: 'row-span-12', + full: 'row-span-full', + auto: 'row-auto' +}; + +export type GridRowSpanType = keyof typeof GridRowSpanType; diff --git a/packages/nitro-react/src/utils/styles/GridRowsType.ts b/packages/nitro-react/src/utils/styles/GridRowsType.ts new file mode 100644 index 0000000..c6b1317 --- /dev/null +++ b/packages/nitro-react/src/utils/styles/GridRowsType.ts @@ -0,0 +1,18 @@ +export const GridRowsType = { + 1: 'grid-rows-1', + 2: 'grid-rows-2', + 3: 'grid-rows-3', + 4: 'grid-rows-4', + 5: 'grid-rows-5', + 6: 'grid-rows-6', + 7: 'grid-rows-7', + 8: 'grid-rows-8', + 9: 'grid-rows-9', + 10: 'grid-rows-10', + 11: 'grid-rows-11', + 12: 'grid-rows-12', + none: 'grid-rows-none', + subgrid: 'grid-rows-subgrid' +}; + +export type GridRowsType = keyof typeof GridRowsType; diff --git a/packages/nitro-react/src/utils/styles/JustifyContentType.ts b/packages/nitro-react/src/utils/styles/JustifyContentType.ts new file mode 100644 index 0000000..8946476 --- /dev/null +++ b/packages/nitro-react/src/utils/styles/JustifyContentType.ts @@ -0,0 +1,12 @@ +export const JustifyContentType = { + start: 'justify-start', + end: 'justify-end', + center: 'justify-center', + between: 'justify-between', + around: 'justify-around', + evenly: 'justify-evenly', + stretch: 'justify-stretch', + normal: 'justify-normal' +}; + +export type JustifyContentType = keyof typeof JustifyContentType; diff --git a/packages/nitro-react/src/utils/styles/JustifyItemsType.ts b/packages/nitro-react/src/utils/styles/JustifyItemsType.ts new file mode 100644 index 0000000..11000e5 --- /dev/null +++ b/packages/nitro-react/src/utils/styles/JustifyItemsType.ts @@ -0,0 +1,9 @@ +export const JustifyItemsType = { + start: 'justify-items-start', + end: 'justify-items-end', + center: 'justify-items-center', + stretch: 'justify-items-stretch', + normal: 'justify-items-normal' +}; + +export type JustifyItemsType = keyof typeof JustifyItemsType; diff --git a/packages/nitro-react/src/utils/styles/JustifySelfType.ts b/packages/nitro-react/src/utils/styles/JustifySelfType.ts new file mode 100644 index 0000000..b035687 --- /dev/null +++ b/packages/nitro-react/src/utils/styles/JustifySelfType.ts @@ -0,0 +1,9 @@ +export const JustifySelfType = { + auto: 'justify-self-auto', + start: 'justify-self-start', + end: 'justify-self-end', + center: 'justify-self-center', + stretch: 'justify-self-stretch' +}; + +export type JustifySelfType = keyof typeof JustifySelfType; diff --git a/packages/nitro-react/src/utils/styles/OverflowType.ts b/packages/nitro-react/src/utils/styles/OverflowType.ts new file mode 100644 index 0000000..55c34fe --- /dev/null +++ b/packages/nitro-react/src/utils/styles/OverflowType.ts @@ -0,0 +1,22 @@ +export const OverflowType = { + all: { + auto: 'overflow-auto', + hidden: 'overflow-hidden', + visible: 'overflow-visible', + scroll: 'overflow-scroll' + }, + x: { + auto: 'overflow-x-auto', + hidden: 'overflow-x-hidden', + visible: 'overflow-x-visible', + scroll: 'overflow-x-scroll' + }, + y: { + auto: 'overflow-y-auto', + hidden: 'overflow-y-hidden', + visible: 'overflow-y-visible', + scroll: 'overflow-y-scroll' + } +}; + +export type OverflowType = keyof typeof OverflowType.all; diff --git a/packages/nitro-react/src/utils/styles/PositionType.ts b/packages/nitro-react/src/utils/styles/PositionType.ts new file mode 100644 index 0000000..f90c0c5 --- /dev/null +++ b/packages/nitro-react/src/utils/styles/PositionType.ts @@ -0,0 +1,9 @@ +export const PositionType = { + static: 'static', + relative: 'relative', + absolute: 'absolute', + fixed: 'fixed', + sticky: 'sticky' +}; + +export type PositionType = keyof typeof PositionType; diff --git a/packages/nitro-react/src/utils/styles/TextColorType.ts b/packages/nitro-react/src/utils/styles/TextColorType.ts new file mode 100644 index 0000000..82a87e1 --- /dev/null +++ b/packages/nitro-react/src/utils/styles/TextColorType.ts @@ -0,0 +1,295 @@ +export const TextColorType = { + inherit: 'text-inherit', + current: 'text-current', + transparent: 'text-transparent', + black: 'text-black', + white: 'text-white', + 'slate-50': 'text-slate-50', + 'slate-100': 'text-slate-100', + 'slate-200': 'text-slate-200', + 'slate-300': 'text-slate-300', + 'slate-400': 'text-slate-400', + 'slate-500': 'text-slate-500', + 'slate-600': 'text-slate-600', + 'slate-700': 'text-slate-700', + 'slate-800': 'text-slate-800', + 'slate-900': 'text-slate-900', + 'slate-950': 'text-slate-950', + 'gray-50': 'text-gray-50', + 'gray-100': 'text-gray-100', + 'gray-200': 'text-gray-200', + 'gray-300': 'text-gray-300', + 'gray-400': 'text-gray-400', + 'gray-500': 'text-gray-500', + 'gray-600': 'text-gray-600', + 'gray-700': 'text-gray-700', + 'gray-800': 'text-gray-800', + 'gray-900': 'text-gray-900', + 'gray-950': 'text-gray-950', + 'zinc-50': 'text-zinc-50', + 'zinc-100': 'text-zinc-100', + 'zinc-200': 'text-zinc-200', + 'zinc-300': 'text-zinc-300', + 'zinc-400': 'text-zinc-400', + 'zinc-500': 'text-zinc-500', + 'zinc-600': 'text-zinc-600', + 'zinc-700': 'text-zinc-700', + 'zinc-800': 'text-zinc-800', + 'zinc-900': 'text-zinc-900', + 'zinc-950': 'text-zinc-950', + 'neutral-50': 'text-neutral-50', + 'neutral-100': 'text-neutral-100', + 'neutral-200': 'text-neutral-200', + 'neutral-300': 'text-neutral-300', + 'neutral-400': 'text-neutral-400', + 'neutral-500': 'text-neutral-500', + 'neutral-600': 'text-neutral-600', + 'neutral-700': 'text-neutral-700', + 'neutral-800': 'text-neutral-800', + 'neutral-900': 'text-neutral-900', + 'neutral-950': 'text-neutral-950', + 'stone-50': 'text-stone-50', + 'stone-100': 'text-stone-100', + 'stone-200': 'text-stone-200', + 'stone-300': 'text-stone-300', + 'stone-400': 'text-stone-400', + 'stone-500': 'text-stone-500', + 'stone-600': 'text-stone-600', + 'stone-700': 'text-stone-700', + 'stone-800': 'text-stone-800', + 'stone-900': 'text-stone-900', + 'stone-950': 'text-stone-950', + 'mauve-50': 'text-mauve-50', + 'mauve-100': 'text-mauve-100', + 'mauve-200': 'text-mauve-200', + 'mauve-300': 'text-mauve-300', + 'mauve-400': 'text-mauve-400', + 'mauve-500': 'text-mauve-500', + 'mauve-600': 'text-mauve-600', + 'mauve-700': 'text-mauve-700', + 'mauve-800': 'text-mauve-800', + 'mauve-900': 'text-mauve-900', + 'mauve-950': 'text-mauve-950', + 'olive-50': 'text-olive-50', + 'olive-100': 'text-olive-100', + 'olive-200': 'text-olive-200', + 'olive-300': 'text-olive-300', + 'olive-400': 'text-olive-400', + 'olive-500': 'text-olive-500', + 'olive-600': 'text-olive-600', + 'olive-700': 'text-olive-700', + 'olive-800': 'text-olive-800', + 'olive-900': 'text-olive-900', + 'olive-950': 'text-olive-950', + 'mist-50': 'text-mist-50', + 'mist-100': 'text-mist-100', + 'mist-200': 'text-mist-200', + 'mist-300': 'text-mist-300', + 'mist-400': 'text-mist-400', + 'mist-500': 'text-mist-500', + 'mist-600': 'text-mist-600', + 'mist-700': 'text-mist-700', + 'mist-800': 'text-mist-800', + 'mist-900': 'text-mist-900', + 'mist-950': 'text-mist-950', + 'taupe-50': 'text-taupe-50', + 'taupe-100': 'text-taupe-100', + 'taupe-200': 'text-taupe-200', + 'taupe-300': 'text-taupe-300', + 'taupe-400': 'text-taupe-400', + 'taupe-500': 'text-taupe-500', + 'taupe-600': 'text-taupe-600', + 'taupe-700': 'text-taupe-700', + 'taupe-800': 'text-taupe-800', + 'taupe-900': 'text-taupe-900', + 'taupe-950': 'text-taupe-950', + 'red-50': 'text-red-50', + 'red-100': 'text-red-100', + 'red-200': 'text-red-200', + 'red-300': 'text-red-300', + 'red-400': 'text-red-400', + 'red-500': 'text-red-500', + 'red-600': 'text-red-600', + 'red-700': 'text-red-700', + 'red-800': 'text-red-800', + 'red-900': 'text-red-900', + 'red-950': 'text-red-950', + 'orange-50': 'text-orange-50', + 'orange-100': 'text-orange-100', + 'orange-200': 'text-orange-200', + 'orange-300': 'text-orange-300', + 'orange-400': 'text-orange-400', + 'orange-500': 'text-orange-500', + 'orange-600': 'text-orange-600', + 'orange-700': 'text-orange-700', + 'orange-800': 'text-orange-800', + 'orange-900': 'text-orange-900', + 'orange-950': 'text-orange-950', + 'amber-50': 'text-amber-50', + 'amber-100': 'text-amber-100', + 'amber-200': 'text-amber-200', + 'amber-300': 'text-amber-300', + 'amber-400': 'text-amber-400', + 'amber-500': 'text-amber-500', + 'amber-600': 'text-amber-600', + 'amber-700': 'text-amber-700', + 'amber-800': 'text-amber-800', + 'amber-900': 'text-amber-900', + 'amber-950': 'text-amber-950', + 'yellow-50': 'text-yellow-50', + 'yellow-100': 'text-yellow-100', + 'yellow-200': 'text-yellow-200', + 'yellow-300': 'text-yellow-300', + 'yellow-400': 'text-yellow-400', + 'yellow-500': 'text-yellow-500', + 'yellow-600': 'text-yellow-600', + 'yellow-700': 'text-yellow-700', + 'yellow-800': 'text-yellow-800', + 'yellow-900': 'text-yellow-900', + 'yellow-950': 'text-yellow-950', + 'lime-50': 'text-lime-50', + 'lime-100': 'text-lime-100', + 'lime-200': 'text-lime-200', + 'lime-300': 'text-lime-300', + 'lime-400': 'text-lime-400', + 'lime-500': 'text-lime-500', + 'lime-600': 'text-lime-600', + 'lime-700': 'text-lime-700', + 'lime-800': 'text-lime-800', + 'lime-900': 'text-lime-900', + 'lime-950': 'text-lime-950', + 'green-50': 'text-green-50', + 'green-100': 'text-green-100', + 'green-200': 'text-green-200', + 'green-300': 'text-green-300', + 'green-400': 'text-green-400', + 'green-500': 'text-green-500', + 'green-600': 'text-green-600', + 'green-700': 'text-green-700', + 'green-800': 'text-green-800', + 'green-900': 'text-green-900', + 'green-950': 'text-green-950', + 'emerald-50': 'text-emerald-50', + 'emerald-100': 'text-emerald-100', + 'emerald-200': 'text-emerald-200', + 'emerald-300': 'text-emerald-300', + 'emerald-400': 'text-emerald-400', + 'emerald-500': 'text-emerald-500', + 'emerald-600': 'text-emerald-600', + 'emerald-700': 'text-emerald-700', + 'emerald-800': 'text-emerald-800', + 'emerald-900': 'text-emerald-900', + 'emerald-950': 'text-emerald-950', + 'teal-50': 'text-teal-50', + 'teal-100': 'text-teal-100', + 'teal-200': 'text-teal-200', + 'teal-300': 'text-teal-300', + 'teal-400': 'text-teal-400', + 'teal-500': 'text-teal-500', + 'teal-600': 'text-teal-600', + 'teal-700': 'text-teal-700', + 'teal-800': 'text-teal-800', + 'teal-900': 'text-teal-900', + 'teal-950': 'text-teal-950', + 'cyan-50': 'text-cyan-50', + 'cyan-100': 'text-cyan-100', + 'cyan-200': 'text-cyan-200', + 'cyan-300': 'text-cyan-300', + 'cyan-400': 'text-cyan-400', + 'cyan-500': 'text-cyan-500', + 'cyan-600': 'text-cyan-600', + 'cyan-700': 'text-cyan-700', + 'cyan-800': 'text-cyan-800', + 'cyan-900': 'text-cyan-900', + 'cyan-950': 'text-cyan-950', + 'sky-50': 'text-sky-50', + 'sky-100': 'text-sky-100', + 'sky-200': 'text-sky-200', + 'sky-300': 'text-sky-300', + 'sky-400': 'text-sky-400', + 'sky-500': 'text-sky-500', + 'sky-600': 'text-sky-600', + 'sky-700': 'text-sky-700', + 'sky-800': 'text-sky-800', + 'sky-900': 'text-sky-900', + 'sky-950': 'text-sky-950', + 'blue-50': 'text-blue-50', + 'blue-100': 'text-blue-100', + 'blue-200': 'text-blue-200', + 'blue-300': 'text-blue-300', + 'blue-400': 'text-blue-400', + 'blue-500': 'text-blue-500', + 'blue-600': 'text-blue-600', + 'blue-700': 'text-blue-700', + 'blue-800': 'text-blue-800', + 'blue-900': 'text-blue-900', + 'blue-950': 'text-blue-950', + 'indigo-50': 'text-indigo-50', + 'indigo-100': 'text-indigo-100', + 'indigo-200': 'text-indigo-200', + 'indigo-300': 'text-indigo-300', + 'indigo-400': 'text-indigo-400', + 'indigo-500': 'text-indigo-500', + 'indigo-600': 'text-indigo-600', + 'indigo-700': 'text-indigo-700', + 'indigo-800': 'text-indigo-800', + 'indigo-900': 'text-indigo-900', + 'indigo-950': 'text-indigo-950', + 'violet-50': 'text-violet-50', + 'violet-100': 'text-violet-100', + 'violet-200': 'text-violet-200', + 'violet-300': 'text-violet-300', + 'violet-400': 'text-violet-400', + 'violet-500': 'text-violet-500', + 'violet-600': 'text-violet-600', + 'violet-700': 'text-violet-700', + 'violet-800': 'text-violet-800', + 'violet-900': 'text-violet-900', + 'violet-950': 'text-violet-950', + 'purple-50': 'text-purple-50', + 'purple-100': 'text-purple-100', + 'purple-200': 'text-purple-200', + 'purple-300': 'text-purple-300', + 'purple-400': 'text-purple-400', + 'purple-500': 'text-purple-500', + 'purple-600': 'text-purple-600', + 'purple-700': 'text-purple-700', + 'purple-800': 'text-purple-800', + 'purple-900': 'text-purple-900', + 'purple-950': 'text-purple-950', + 'fuchsia-50': 'text-fuchsia-50', + 'fuchsia-100': 'text-fuchsia-100', + 'fuchsia-200': 'text-fuchsia-200', + 'fuchsia-300': 'text-fuchsia-300', + 'fuchsia-400': 'text-fuchsia-400', + 'fuchsia-500': 'text-fuchsia-500', + 'fuchsia-600': 'text-fuchsia-600', + 'fuchsia-700': 'text-fuchsia-700', + 'fuchsia-800': 'text-fuchsia-800', + 'fuchsia-900': 'text-fuchsia-900', + 'fuchsia-950': 'text-fuchsia-950', + 'pink-50': 'text-pink-50', + 'pink-100': 'text-pink-100', + 'pink-200': 'text-pink-200', + 'pink-300': 'text-pink-300', + 'pink-400': 'text-pink-400', + 'pink-500': 'text-pink-500', + 'pink-600': 'text-pink-600', + 'pink-700': 'text-pink-700', + 'pink-800': 'text-pink-800', + 'pink-900': 'text-pink-900', + 'pink-950': 'text-pink-950', + 'rose-50': 'text-rose-50', + 'rose-100': 'text-rose-100', + 'rose-200': 'text-rose-200', + 'rose-300': 'text-rose-300', + 'rose-400': 'text-rose-400', + 'rose-500': 'text-rose-500', + 'rose-600': 'text-rose-600', + 'rose-700': 'text-rose-700', + 'rose-800': 'text-rose-800', + 'rose-900': 'text-rose-900', + 'rose-950': 'text-rose-950' +}; + +export type TextColorType = keyof typeof TextColorType; diff --git a/packages/nitro-react/src/utils/styles/index.ts b/packages/nitro-react/src/utils/styles/index.ts new file mode 100644 index 0000000..b58999c --- /dev/null +++ b/packages/nitro-react/src/utils/styles/index.ts @@ -0,0 +1,23 @@ +export * from './AlignContentType'; +export * from './AlignItemsType'; +export * from './AlignSelfType'; +export * from './CursorType'; +export * from './DisplayType'; +export * from './FlexDirectionType'; +export * from './FlexGrowType'; +export * from './FlexShrinkType'; +export * from './FlexType'; +export * from './FlexWrapType'; +export * from './GapType'; +export * from './GridColSpanType'; +export * from './GridColStartType'; +export * from './GridColumnsType'; +export * from './GridFlowType'; +export * from './GridRowSpanType'; +export * from './GridRowsType'; +export * from './JustifyContentType'; +export * from './JustifyItemsType'; +export * from './JustifySelfType'; +export * from './OverflowType'; +export * from './PositionType'; +export * from './TextColorType'; diff --git a/packages/nitro-react/src/utils/utils.ts b/packages/nitro-react/src/utils/utils.ts index 6eb81f6..fcd307c 100644 --- a/packages/nitro-react/src/utils/utils.ts +++ b/packages/nitro-react/src/utils/utils.ts @@ -55,4 +55,12 @@ export function cva>>( }; } +export function extractNumber(value: number | string | undefined, fallback: number): number { + if (value == null) return fallback; + + const parsed = Number(value); + + return Number.isFinite(parsed) ? parsed : fallback; +} + export type { VariantProps }; \ No newline at end of file diff --git a/packages/nitro-react/src/views/room-widgets/object-infostand/InfostandUserView.tsx b/packages/nitro-react/src/views/room-widgets/object-infostand/InfostandUserView.tsx index a94b48a..55c6b07 100644 --- a/packages/nitro-react/src/views/room-widgets/object-infostand/InfostandUserView.tsx +++ b/packages/nitro-react/src/views/room-widgets/object-infostand/InfostandUserView.tsx @@ -69,7 +69,7 @@ export const InfostandUserView = (props: InfostandUserViewProps) => {
{!userData.isOwnUser &&

{motto.length === 0 ? getLocalizationValue('infostand.motto.change') : motto}

} {userData.isOwnUser && <> - setIsEditingMotto(true)} /> + setIsEditingMotto(true)} /> {!isEditingMotto &&

{motto}

} {isEditingMotto && setMotto(e.target.value)} onKeyDown={onMottoKeyDown} autoFocus={true} />} } diff --git a/packages/nitro-react/src/views/room-widgets/object-menu/InfoBubbleAvatarView.tsx b/packages/nitro-react/src/views/room-widgets/object-menu/InfoBubbleAvatarView.tsx index b57acd0..5f43a5f 100644 --- a/packages/nitro-react/src/views/room-widgets/object-menu/InfoBubbleAvatarView.tsx +++ b/packages/nitro-react/src/views/room-widgets/object-menu/InfoBubbleAvatarView.tsx @@ -269,7 +269,7 @@ export const InfoBubbleAvatarView = (props: InfoBubbleAvatarViewProps) => {
}
setCollapsed(!collapsed)}> - +
); diff --git a/packages/nitro-react/src/views/room-widgets/object-menu/InfoBubbleOwnAvatarView.tsx b/packages/nitro-react/src/views/room-widgets/object-menu/InfoBubbleOwnAvatarView.tsx index 8944c54..d89e280 100644 --- a/packages/nitro-react/src/views/room-widgets/object-menu/InfoBubbleOwnAvatarView.tsx +++ b/packages/nitro-react/src/views/room-widgets/object-menu/InfoBubbleOwnAvatarView.tsx @@ -207,7 +207,7 @@ export const InfoBubbleOwnAvatarView = (props: InfoBubbleOwnAvatarViewProps) =>
}
setCollapsed(!collapsed)}> - +
); diff --git a/packages/nitro-react/src/views/toolbar/ToolbarMeMenu.tsx b/packages/nitro-react/src/views/toolbar/ToolbarMeMenuView.tsx similarity index 66% rename from packages/nitro-react/src/views/toolbar/ToolbarMeMenu.tsx rename to packages/nitro-react/src/views/toolbar/ToolbarMeMenuView.tsx index ca0e397..fbdf167 100644 --- a/packages/nitro-react/src/views/toolbar/ToolbarMeMenu.tsx +++ b/packages/nitro-react/src/views/toolbar/ToolbarMeMenuView.tsx @@ -3,30 +3,30 @@ import { forwardRef } from 'react'; import { NitroIcon } from '#base/components'; import { useLocalizationStore } from '#base/stores'; -export const ToolbarMeMenu = forwardRef((props, ref) => { +export const ToolbarMeMenuView = forwardRef((props, ref) => { const getLocalizationValue = useLocalizationStore(x => x.getLocalizationValue); return (
- {getLocalizationValue('widget.memenu.profile')} + { getLocalizationValue('widget.memenu.profile') }
- {getLocalizationValue('widget.memenu.myrooms')} + { getLocalizationValue('widget.memenu.myrooms') }
- {getLocalizationValue('widget.memenu.myclothes')} + { getLocalizationValue('widget.memenu.myclothes') }
- {getLocalizationValue('widget.memenu.forums')} + { getLocalizationValue('widget.memenu.forums') }
- {getLocalizationValue('memenu.collectibles')} + { getLocalizationValue('memenu.collectibles') }
); diff --git a/packages/nitro-react/src/views/toolbar/ToolbarProgressionMenu.tsx b/packages/nitro-react/src/views/toolbar/ToolbarProgressionMenuView.tsx similarity index 65% rename from packages/nitro-react/src/views/toolbar/ToolbarProgressionMenu.tsx rename to packages/nitro-react/src/views/toolbar/ToolbarProgressionMenuView.tsx index a05aabb..8bd6efd 100644 --- a/packages/nitro-react/src/views/toolbar/ToolbarProgressionMenu.tsx +++ b/packages/nitro-react/src/views/toolbar/ToolbarProgressionMenuView.tsx @@ -3,30 +3,30 @@ import { forwardRef } from 'react'; import { NitroIcon } from '#base/components'; import { useLocalizationStore } from '#base/stores'; -export const ToolbarProgressionMenu = forwardRef((props, ref) => { +export const ToolbarProgressionMenuView = forwardRef((props, ref) => { const getLocalizationValue = useLocalizationStore(x => x.getLocalizationValue); return (
- {getLocalizationValue('widget.progmenu.dailytasks')} + { getLocalizationValue('widget.progmenu.dailytasks') }
- {getLocalizationValue('widget.progmenu.quests')} + { getLocalizationValue('widget.progmenu.quests') }
- {getLocalizationValue('widget.progmenu.achievements')} + { getLocalizationValue('widget.progmenu.achievements') }
- {getLocalizationValue('widget.progmenu.leaderboards')} + { getLocalizationValue('widget.progmenu.leaderboards') }
- {getLocalizationValue('widget.progmenu.introduction')} + { getLocalizationValue('widget.progmenu.introduction') }
); diff --git a/packages/nitro-react/src/views/toolbar/ToolbarView.tsx b/packages/nitro-react/src/views/toolbar/ToolbarView.tsx index 3a4a2a3..8ad2f04 100644 --- a/packages/nitro-react/src/views/toolbar/ToolbarView.tsx +++ b/packages/nitro-react/src/views/toolbar/ToolbarView.tsx @@ -1,14 +1,17 @@ import { useRef, useState } from 'react'; -import { NitroIcon } from '#base/components'; +import { Base, NitroIcon } from '#base/components'; import { AvatarImage } from '#base/components/AvatarImage'; import { useOwnUserFigure, useOwnUserGender } from '#base/context'; +import { useLocalizationStore } from '#base/stores'; import { cn } from '#base/utils'; -import { ToolbarMeMenu } from './ToolbarMeMenu'; -import { ToolbarProgressionMenu } from './ToolbarProgressionMenu'; +import { ToolbarMeMenuView } from './ToolbarMeMenuView'; +import { ToolbarProgressionMenuView } from './ToolbarProgressionMenuView'; export const ToolbarView = () => { + const getLocalizationValue = useLocalizationStore(x => x.getLocalizationValue); + const [isMeExpanded, setMeExpanded] = useState(false); const [isProgressionExpanded, setProgressionExpanded] = useState(false); const [leftSideCollapsed, setLeftSideCollapsed] = useState(false); @@ -25,26 +28,26 @@ export const ToolbarView = () => { return ( <> - {isMeExpanded && } - {isProgressionExpanded && } + {isMeExpanded && } + {isProgressionExpanded && }
setLeftSideCollapsed(prev => !prev)} /> - - - toggleMenu('progression')} /> - - - -
toggleMenu('me')} > + + + toggleMenu('progression')} /> + + + + toggleMenu('me')} > -
- - + + +
- - + +
setRightSideCollapsed(!rightSideCollapsed)} />
diff --git a/packages/nitro-react/tsconfig.json b/packages/nitro-react/tsconfig.json index a7f8fec..ff715fd 100644 --- a/packages/nitro-react/tsconfig.json +++ b/packages/nitro-react/tsconfig.json @@ -24,6 +24,9 @@ "#base/utils": [ "./src/utils/index.ts" ], + "#base/utils/styles": [ + "./src/utils/styles/index.ts" + ], "#base/*": [ "./src/*" ],