diff --git a/packages/react-components/react-timepicker-compat-preview/etc/react-timepicker-compat-preview.api.md b/packages/react-components/react-timepicker-compat-preview/etc/react-timepicker-compat-preview.api.md index 8b44d09200ef18..267bfedecba0c5 100644 --- a/packages/react-components/react-timepicker-compat-preview/etc/react-timepicker-compat-preview.api.md +++ b/packages/react-components/react-timepicker-compat-preview/etc/react-timepicker-compat-preview.api.md @@ -4,6 +4,39 @@ ```ts +import type { ComponentProps } from '@fluentui/react-utilities'; +import type { ComponentState } from '@fluentui/react-utilities'; +import type { ForwardRefComponent } from '@fluentui/react-utilities'; +import * as React_2 from 'react'; +import type { Slot } from '@fluentui/react-utilities'; +import type { SlotClassNames } from '@fluentui/react-utilities'; + +// @public +export const renderTimePicker_unstable: (state: TimePickerState) => JSX.Element; + +// @public +export const TimePicker: ForwardRefComponent; + +// @public (undocumented) +export const timePickerClassNames: SlotClassNames; + +// @public +export type TimePickerProps = ComponentProps & {}; + +// @public (undocumented) +export type TimePickerSlots = { + root: Slot<'div'>; +}; + +// @public +export type TimePickerState = ComponentState; + +// @public +export const useTimePicker_unstable: (props: TimePickerProps, ref: React_2.Ref) => TimePickerState; + +// @public +export const useTimePickerStyles_unstable: (state: TimePickerState) => TimePickerState; + // (No @packageDocumentation comment for this package) ``` diff --git a/packages/react-components/react-timepicker-compat-preview/src/TimePicker.ts b/packages/react-components/react-timepicker-compat-preview/src/TimePicker.ts new file mode 100644 index 00000000000000..fb8fc412805e6d --- /dev/null +++ b/packages/react-components/react-timepicker-compat-preview/src/TimePicker.ts @@ -0,0 +1 @@ +export * from './components/TimePicker/index'; diff --git a/packages/react-components/react-timepicker-compat-preview/src/components/TimePicker/TimePicker.test.tsx b/packages/react-components/react-timepicker-compat-preview/src/components/TimePicker/TimePicker.test.tsx new file mode 100644 index 00000000000000..727eb66efdfc84 --- /dev/null +++ b/packages/react-components/react-timepicker-compat-preview/src/components/TimePicker/TimePicker.test.tsx @@ -0,0 +1,9 @@ +import { isConformant } from '../../testing/isConformant'; +import { TimePicker } from './TimePicker'; + +describe('TimePicker', () => { + isConformant({ + Component: TimePicker, + displayName: 'TimePicker', + }); +}); diff --git a/packages/react-components/react-timepicker-compat-preview/src/components/TimePicker/TimePicker.tsx b/packages/react-components/react-timepicker-compat-preview/src/components/TimePicker/TimePicker.tsx new file mode 100644 index 00000000000000..2bfa56e581d6e2 --- /dev/null +++ b/packages/react-components/react-timepicker-compat-preview/src/components/TimePicker/TimePicker.tsx @@ -0,0 +1,18 @@ +import * as React from 'react'; +import type { ForwardRefComponent } from '@fluentui/react-utilities'; +import { useTimePicker_unstable } from './useTimePicker'; +import { renderTimePicker_unstable } from './renderTimePicker'; +import { useTimePickerStyles_unstable } from './useTimePickerStyles.styles'; +import type { TimePickerProps } from './TimePicker.types'; + +/** + * TimePicker component - TODO: add more docs + */ +export const TimePicker: ForwardRefComponent = React.forwardRef((props, ref) => { + const state = useTimePicker_unstable(props, ref); + + useTimePickerStyles_unstable(state); + return renderTimePicker_unstable(state); +}); + +TimePicker.displayName = 'TimePicker'; diff --git a/packages/react-components/react-timepicker-compat-preview/src/components/TimePicker/TimePicker.types.ts b/packages/react-components/react-timepicker-compat-preview/src/components/TimePicker/TimePicker.types.ts new file mode 100644 index 00000000000000..78e0c33962ca3f --- /dev/null +++ b/packages/react-components/react-timepicker-compat-preview/src/components/TimePicker/TimePicker.types.ts @@ -0,0 +1,17 @@ +import type { ComponentProps, ComponentState, Slot } from '@fluentui/react-utilities'; + +export type TimePickerSlots = { + root: Slot<'div'>; +}; + +/** + * TimePicker Props + */ +export type TimePickerProps = ComponentProps & {}; + +/** + * State used in rendering TimePicker + */ +export type TimePickerState = ComponentState; +// TODO: Remove semicolon from previous line, uncomment next line, and provide union of props to pick from TimePickerProps. +// & Required> diff --git a/packages/react-components/react-timepicker-compat-preview/src/components/TimePicker/index.ts b/packages/react-components/react-timepicker-compat-preview/src/components/TimePicker/index.ts new file mode 100644 index 00000000000000..e27956fb916e39 --- /dev/null +++ b/packages/react-components/react-timepicker-compat-preview/src/components/TimePicker/index.ts @@ -0,0 +1,5 @@ +export * from './TimePicker'; +export * from './TimePicker.types'; +export * from './renderTimePicker'; +export * from './useTimePicker'; +export * from './useTimePickerStyles.styles'; diff --git a/packages/react-components/react-timepicker-compat-preview/src/components/TimePicker/renderTimePicker.tsx b/packages/react-components/react-timepicker-compat-preview/src/components/TimePicker/renderTimePicker.tsx new file mode 100644 index 00000000000000..d0f84c293529c4 --- /dev/null +++ b/packages/react-components/react-timepicker-compat-preview/src/components/TimePicker/renderTimePicker.tsx @@ -0,0 +1,16 @@ +/** @jsxRuntime classic */ +/** @jsx createElement */ + +import { createElement } from '@fluentui/react-jsx-runtime'; +import { assertSlots } from '@fluentui/react-utilities'; +import type { TimePickerState, TimePickerSlots } from './TimePicker.types'; + +/** + * Render the final JSX of TimePicker + */ +export const renderTimePicker_unstable = (state: TimePickerState) => { + assertSlots(state); + + // TODO Add additional slots in the appropriate place + return ; +}; diff --git a/packages/react-components/react-timepicker-compat-preview/src/components/TimePicker/useTimePicker.ts b/packages/react-components/react-timepicker-compat-preview/src/components/TimePicker/useTimePicker.ts new file mode 100644 index 00000000000000..ed3823045090ab --- /dev/null +++ b/packages/react-components/react-timepicker-compat-preview/src/components/TimePicker/useTimePicker.ts @@ -0,0 +1,31 @@ +import * as React from 'react'; +import { getNativeElementProps, slot } from '@fluentui/react-utilities'; +import type { TimePickerProps, TimePickerState } from './TimePicker.types'; + +/** + * Create the state required to render TimePicker. + * + * The returned state can be modified with hooks such as useTimePickerStyles_unstable, + * before being passed to renderTimePicker_unstable. + * + * @param props - props from this instance of TimePicker + * @param ref - reference to root HTMLElement of TimePicker + */ +export const useTimePicker_unstable = (props: TimePickerProps, ref: React.Ref): TimePickerState => { + return { + // TODO add appropriate props/defaults + components: { + // TODO add each slot's element type or component + root: 'div', + }, + // TODO add appropriate slots, for example: + // mySlot: resolveShorthand(props.mySlot), + root: slot.always( + getNativeElementProps('div', { + ref, + ...props, + }), + { elementType: 'div' }, + ), + }; +}; diff --git a/packages/react-components/react-timepicker-compat-preview/src/components/TimePicker/useTimePickerStyles.styles.ts b/packages/react-components/react-timepicker-compat-preview/src/components/TimePicker/useTimePickerStyles.styles.ts new file mode 100644 index 00000000000000..9c448719b80ed4 --- /dev/null +++ b/packages/react-components/react-timepicker-compat-preview/src/components/TimePicker/useTimePickerStyles.styles.ts @@ -0,0 +1,33 @@ +import { makeStyles, mergeClasses } from '@griffel/react'; +import type { SlotClassNames } from '@fluentui/react-utilities'; +import type { TimePickerSlots, TimePickerState } from './TimePicker.types'; + +export const timePickerClassNames: SlotClassNames = { + root: 'fui-TimePicker', + // TODO: add class names for all slots on TimePickerSlots. + // Should be of the form `: 'fui-TimePicker__` +}; + +/** + * Styles for the root slot + */ +const useStyles = makeStyles({ + root: { + // TODO Add default styles for the root element + }, + + // TODO add additional classes for different states and/or slots +}); + +/** + * Apply styling to the TimePicker slots based on the state + */ +export const useTimePickerStyles_unstable = (state: TimePickerState): TimePickerState => { + const styles = useStyles(); + state.root.className = mergeClasses(timePickerClassNames.root, styles.root, state.root.className); + + // TODO Add class names to slots, for example: + // state.mySlot.className = mergeClasses(styles.mySlot, state.mySlot.className); + + return state; +}; diff --git a/packages/react-components/react-timepicker-compat-preview/src/index.ts b/packages/react-components/react-timepicker-compat-preview/src/index.ts index cb0ff5c3b541f6..cbc71621f6968c 100644 --- a/packages/react-components/react-timepicker-compat-preview/src/index.ts +++ b/packages/react-components/react-timepicker-compat-preview/src/index.ts @@ -1 +1,8 @@ -export {}; +export { + TimePicker, + renderTimePicker_unstable, + timePickerClassNames, + useTimePickerStyles_unstable, + useTimePicker_unstable, +} from './TimePicker'; +export type { TimePickerProps, TimePickerSlots, TimePickerState } from './TimePicker'; diff --git a/packages/react-components/react-timepicker-compat-preview/stories/TimePicker/TimePickerBestPractices.md b/packages/react-components/react-timepicker-compat-preview/stories/TimePicker/TimePickerBestPractices.md new file mode 100644 index 00000000000000..08ff8ddeeb5f86 --- /dev/null +++ b/packages/react-components/react-timepicker-compat-preview/stories/TimePicker/TimePickerBestPractices.md @@ -0,0 +1,5 @@ +## Best practices + +### Do + +### Don't diff --git a/packages/react-components/react-timepicker-compat-preview/stories/TimePicker/TimePickerDefault.stories.tsx b/packages/react-components/react-timepicker-compat-preview/stories/TimePicker/TimePickerDefault.stories.tsx new file mode 100644 index 00000000000000..8ff5f40f307525 --- /dev/null +++ b/packages/react-components/react-timepicker-compat-preview/stories/TimePicker/TimePickerDefault.stories.tsx @@ -0,0 +1,4 @@ +import * as React from 'react'; +import { TimePicker, TimePickerProps } from '@fluentui/react-timepicker-compat-preview'; + +export const Default = (props: Partial) => ; diff --git a/packages/react-components/react-timepicker-compat-preview/stories/TimePicker/TimePickerDescription.md b/packages/react-components/react-timepicker-compat-preview/stories/TimePicker/TimePickerDescription.md new file mode 100644 index 00000000000000..e69de29bb2d1d6 diff --git a/packages/react-components/react-timepicker-compat-preview/stories/TimePicker/index.stories.tsx b/packages/react-components/react-timepicker-compat-preview/stories/TimePicker/index.stories.tsx new file mode 100644 index 00000000000000..17045d9a7e4fb7 --- /dev/null +++ b/packages/react-components/react-timepicker-compat-preview/stories/TimePicker/index.stories.tsx @@ -0,0 +1,18 @@ +import { TimePicker } from '@fluentui/react-timepicker-compat-preview'; + +import descriptionMd from './TimePickerDescription.md'; +import bestPracticesMd from './TimePickerBestPractices.md'; + +export { Default } from './TimePickerDefault.stories'; + +export default { + title: 'Preview Components/TimePicker', + component: TimePicker, + parameters: { + docs: { + description: { + component: [descriptionMd, bestPracticesMd].join('\n'), + }, + }, + }, +};