chore(ui,icons,ui-preset,toolbox): Move design system packages to monorepo (#5470)

This commit is contained in:
Kasper Fabricius Kristensen
2023-11-07 22:17:44 +01:00
committed by GitHub
parent 71853eafdd
commit e4ce2f4e07
722 changed files with 30300 additions and 186 deletions

View File

@@ -0,0 +1 @@
export * from "./time-input"

View File

@@ -0,0 +1,56 @@
import type { Meta, StoryObj } from "@storybook/react"
import * as React from "react"
import { isBrowserLocaleClockType24h } from "../../utils/is-browser-locale-hour-cycle-24h"
import { TimeInput } from "./time-input"
const meta: Meta<typeof TimeInput> = {
title: "Components/TimeInput",
component: TimeInput,
parameters: {
layout: "centered",
},
render: (args) => (
<div className="w-[300px]">
<TimeInput aria-labelledby="time" {...args} />
</div>
),
}
export default meta
type Story = StoryObj<typeof TimeInput>
// Hour Cycle defaults to your browser's locale.
export const Default: Story = {
render: (args) => {
return (
<div className="flex flex-col gap-y-4">
<TimeInput aria-labelledby="time" {...args} />
<div className="flex flex-col gap-y-2">
<p className="text-xs">
Will use 24h or 12h cycle depending on your locale
</p>
<div className="text-xs">
<pre>
Locale: {window.navigator.language}, Hour Cycle:{" "}
{isBrowserLocaleClockType24h() ? "24h" : "12h"}
</pre>
</div>
</div>
</div>
)
},
}
export const Hour24: Story = {
args: {
hourCycle: 24,
},
}
export const Hour12: Story = {
args: {
hourCycle: 12,
},
}

View File

@@ -0,0 +1,118 @@
"use client"
import {
AriaTimeFieldProps,
TimeValue,
useDateSegment,
useTimeField,
} from "@react-aria/datepicker"
import {
useTimeFieldState,
type DateFieldState,
type DateSegment,
} from "@react-stately/datepicker"
import * as React from "react"
import { inputBaseStyles } from "@/components/input"
import { clx } from "@/utils/clx"
type TimeSegmentProps = {
segment: DateSegment
state: DateFieldState
}
const TimeSegment = ({ segment, state }: TimeSegmentProps) => {
const ref = React.useRef<HTMLDivElement>(null)
const { segmentProps } = useDateSegment(segment, state, ref)
const isColon = segment.type === "literal" && segment.text === ":"
const isSpace = segment.type === "literal" && segment.text === ""
const isDecorator = isColon || isSpace
return (
<div
{...segmentProps}
ref={ref}
className={clx(
"txt-compact-medium w-full rounded-md px-2 py-[5px] text-left uppercase tabular-nums",
inputBaseStyles,
"group-aria-[invalid=true]/time-input:!shadow-borders-error group-invalid/time-input:!shadow-borders-error",
{
"text-ui-fg-muted !w-fit border-none bg-transparent px-0 shadow-none":
isDecorator,
hidden: isSpace,
"text-ui-fg-disabled bg-ui-bg-disabled border-ui-border-base shadow-none":
state.isDisabled,
"!text-ui-fg-muted !bg-transparent": !segment.isEditable,
}
)}
>
<span
aria-hidden="true"
className={clx(
"txt-compact-medium text-ui-fg-muted pointer-events-none block w-full text-left",
{
hidden: !segment.isPlaceholder,
"h-0": !segment.isPlaceholder,
}
)}
>
{segment.placeholder}
</span>
{segment.isPlaceholder ? "" : segment.text}
</div>
)
}
type TimeInputProps = Omit<
AriaTimeFieldProps<TimeValue>,
"label" | "shouldForceLeadingZeros" | "description" | "errorMessage"
>
const TimeInput = React.forwardRef<HTMLDivElement, TimeInputProps>(
({ hourCycle, ...props }: TimeInputProps, ref) => {
const innerRef = React.useRef<HTMLDivElement>(null)
React.useImperativeHandle<HTMLDivElement | null, HTMLDivElement | null>(
ref,
() => innerRef?.current
)
const locale = window !== undefined ? window.navigator.language : "en-US"
const state = useTimeFieldState({
hourCycle: hourCycle,
locale: locale,
shouldForceLeadingZeros: true,
autoFocus: true,
...props,
})
const { fieldProps } = useTimeField(
{
...props,
hourCycle: hourCycle,
shouldForceLeadingZeros: true,
},
state,
innerRef
)
return (
<div
{...fieldProps}
ref={innerRef}
className="group/time-input inline-flex w-full gap-x-2"
>
{state.segments.map((segment, i) => (
<TimeSegment key={i} segment={segment} state={state} />
))}
</div>
)
}
)
TimeInput.displayName = "TimeInput"
export { TimeInput }