@bronzelabs/oakma-ui 0.0.1 → 0.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +345 -0
- package/dist/index.js +2 -0
- package/dist/oakma-ui.css +2 -0
- package/package.json +7 -2
- package/.prettierrc.cjs +0 -25
- package/.storybook/components/ActionButton.tsx +0 -44
- package/.storybook/components/DummyIcons.tsx +0 -47
- package/.storybook/components/index.ts +0 -2
- package/.storybook/docs/blocks/ImportStatement.tsx +0 -52
- package/.storybook/docs/blocks/index.ts +0 -1
- package/.storybook/docs/page.tsx +0 -41
- package/.storybook/main.ts +0 -21
- package/.storybook/postcss.config.cjs +0 -8
- package/.storybook/preview-body.html +0 -20
- package/.storybook/preview-head.html +0 -6
- package/.storybook/preview.tsx +0 -30
- package/.storybook/tailwind.css +0 -6
- package/.storybook/utils/index.ts +0 -2
- package/.storybook/utils/renderAsReact.tsx +0 -30
- package/.storybook/utils/renderDocsWithProps.tsx +0 -22
- package/@types/markdown.d.ts +0 -4
- package/eslint.config.js +0 -91
- package/postcss.config.cjs +0 -8
- package/scripts/release.sh +0 -76
- package/src/components/Button/Button.stories.tsx +0 -314
- package/src/components/Button/Button.tsx +0 -132
- package/src/components/Button/index.ts +0 -2
- package/src/components/Button/types.ts +0 -19
- package/src/components/Checkbox/Checkbox.stories.tsx +0 -152
- package/src/components/Checkbox/Checkbox.tsx +0 -90
- package/src/components/Checkbox/index.ts +0 -2
- package/src/components/Checkbox/types.ts +0 -6
- package/src/components/Chip/Chip.stories.tsx +0 -146
- package/src/components/Chip/Chip.tsx +0 -59
- package/src/components/Chip/index.ts +0 -2
- package/src/components/Chip/types.ts +0 -6
- package/src/components/Drawer/Drawer.docs.md +0 -88
- package/src/components/Drawer/Drawer.stories.tsx +0 -239
- package/src/components/Drawer/Drawer.tsx +0 -194
- package/src/components/Drawer/index.ts +0 -3
- package/src/components/Drawer/types.ts +0 -3
- package/src/components/Dropdown/AsyncDropdown.tsx +0 -105
- package/src/components/Dropdown/Dropdown.docs.md +0 -33
- package/src/components/Dropdown/Dropdown.stories.tsx +0 -419
- package/src/components/Dropdown/Dropdown.tsx +0 -104
- package/src/components/Dropdown/MultiValue.tsx +0 -19
- package/src/components/Dropdown/ValueContainer.tsx +0 -114
- package/src/components/Dropdown/index.ts +0 -4
- package/src/components/Dropdown/types.ts +0 -29
- package/src/components/Dropdown/useDropdown.tsx +0 -257
- package/src/components/Logo/Logo.stories.tsx +0 -130
- package/src/components/Logo/Logo.tsx +0 -80
- package/src/components/Logo/index.ts +0 -2
- package/src/components/Modal/Modal.docs.md +0 -94
- package/src/components/Modal/Modal.stories.tsx +0 -318
- package/src/components/Modal/Modal.tsx +0 -217
- package/src/components/Modal/index.ts +0 -1
- package/src/components/MultiSelect/AsyncMultiSelect.tsx +0 -47
- package/src/components/MultiSelect/MultiSelect.docs.md +0 -37
- package/src/components/MultiSelect/MultiSelect.stories.tsx +0 -493
- package/src/components/MultiSelect/MultiSelect.tsx +0 -81
- package/src/components/MultiSelect/index.ts +0 -2
- package/src/components/Notification/Notification.stories.tsx +0 -158
- package/src/components/Notification/Notification.tsx +0 -110
- package/src/components/Notification/index.ts +0 -1
- package/src/components/Notification/types.ts +0 -11
- package/src/components/Notifications/Notifications.docs.md +0 -103
- package/src/components/Notifications/Notifications.stories.tsx +0 -159
- package/src/components/Notifications/Notifications.tsx +0 -90
- package/src/components/Notifications/NotificationsContext.tsx +0 -90
- package/src/components/Notifications/index.ts +0 -7
- package/src/components/Select/Select.stories.tsx +0 -234
- package/src/components/Select/Select.tsx +0 -129
- package/src/components/Select/index.ts +0 -2
- package/src/components/Select/types.ts +0 -1
- package/src/components/Spinner/Spinner.stories.tsx +0 -55
- package/src/components/Spinner/Spinner.tsx +0 -48
- package/src/components/Spinner/index.ts +0 -2
- package/src/components/Spinner/types.ts +0 -8
- package/src/components/TextArea/TextArea.stories.tsx +0 -243
- package/src/components/TextArea/TextArea.tsx +0 -133
- package/src/components/TextArea/index.ts +0 -2
- package/src/components/TextArea/types.ts +0 -4
- package/src/components/TextField/Container.tsx +0 -68
- package/src/components/TextField/ErrorMessage.tsx +0 -37
- package/src/components/TextField/Icon.tsx +0 -77
- package/src/components/TextField/Label.tsx +0 -56
- package/src/components/TextField/NotchBorder.tsx +0 -67
- package/src/components/TextField/index.ts +0 -14
- package/src/components/TextField/types.ts +0 -15
- package/src/components/TextField/useInputKeyboardFocus.tsx +0 -63
- package/src/components/TextInput/TextInput.stories.tsx +0 -384
- package/src/components/TextInput/TextInput.tsx +0 -255
- package/src/components/TextInput/index.ts +0 -2
- package/src/components/TextInput/types.ts +0 -4
- package/src/components/Toggle/Toggle.stories.tsx +0 -142
- package/src/components/Toggle/Toggle.tsx +0 -69
- package/src/components/Toggle/index.ts +0 -1
- package/src/hooks/index.ts +0 -6
- package/src/hooks/useCombinedRefs.ts +0 -37
- package/src/hooks/useEventListener.ts +0 -87
- package/src/hooks/useFocusTrap/createAriaHider.ts +0 -62
- package/src/hooks/useFocusTrap/index.ts +0 -1
- package/src/hooks/useFocusTrap/scopeTab.ts +0 -46
- package/src/hooks/useFocusTrap/tabbable.ts +0 -107
- package/src/hooks/useFocusTrap/useFocusTrap.ts +0 -97
- package/src/hooks/useIsomorphicLayoutEffect.ts +0 -14
- package/src/hooks/useLockBodyScroll.ts +0 -24
- package/src/hooks/useOnClickOutside.ts +0 -53
- package/src/index.ts +0 -22
- package/src/tailwind.css +0 -4
- package/src/types/helpers.ts +0 -11
- package/src/types/polymorphic.ts +0 -39
- package/src/utils/animation/variants.ts +0 -21
- package/src/utils/array/index.ts +0 -1
- package/src/utils/array/uniqBy.ts +0 -12
- package/src/utils/common/index.ts +0 -1
- package/src/utils/common/isFunction.ts +0 -17
- package/src/utils/react/extractDisplayName.ts +0 -15
- package/src/utils/react/index.ts +0 -1
- package/tsconfig.json +0 -16
- package/tsconfig.production.json +0 -19
- package/tsup.config.ts +0 -16
|
@@ -1,90 +0,0 @@
|
|
|
1
|
-
import React, { useCallback, useState, use } from "react"
|
|
2
|
-
|
|
3
|
-
// Types
|
|
4
|
-
import type { NotificationData } from "../Notification"
|
|
5
|
-
import type { PickPartial, SingleOrArray } from "../../types/helpers"
|
|
6
|
-
|
|
7
|
-
export type NotificationsContextType = {
|
|
8
|
-
/** Array of notifications. */
|
|
9
|
-
notifications: NotificationData[]
|
|
10
|
-
/** Function to add a notification to the state. */
|
|
11
|
-
addNotification: (
|
|
12
|
-
notifications: SingleOrArray<PickPartial<NotificationData, "id" | "timestamp">>,
|
|
13
|
-
withTimeout?: boolean,
|
|
14
|
-
) => void
|
|
15
|
-
/** Function to remove a notification from the state. */
|
|
16
|
-
removeNotification: (id?: string) => void
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
// Utils
|
|
20
|
-
import { uniqBy } from "../../utils/array"
|
|
21
|
-
|
|
22
|
-
// Context
|
|
23
|
-
const NotificationsContext = React.createContext<NotificationsContextType>({
|
|
24
|
-
notifications: [],
|
|
25
|
-
addNotification: () => {
|
|
26
|
-
return
|
|
27
|
-
},
|
|
28
|
-
removeNotification: () => {
|
|
29
|
-
return
|
|
30
|
-
},
|
|
31
|
-
})
|
|
32
|
-
|
|
33
|
-
/*
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
*/
|
|
39
|
-
|
|
40
|
-
const NotificationsProvider: React.FC<React.PropsWithChildren> = ({ children }) => {
|
|
41
|
-
// State
|
|
42
|
-
const [notificationsState, setNotificationsState] = useState<NotificationData[]>([])
|
|
43
|
-
|
|
44
|
-
// Functions
|
|
45
|
-
const removeNotification = useCallback((id?: string) => {
|
|
46
|
-
if (typeof id !== "string") return
|
|
47
|
-
|
|
48
|
-
setNotificationsState(curr => curr.filter(n => n?.id !== id))
|
|
49
|
-
}, [])
|
|
50
|
-
|
|
51
|
-
const addNotification = useCallback<NotificationsContextType["addNotification"]>(
|
|
52
|
-
(notifications, withTimeout = true) => {
|
|
53
|
-
const data = Array.isArray(notifications) ? notifications : [notifications]
|
|
54
|
-
|
|
55
|
-
data.forEach(n => {
|
|
56
|
-
n.timestamp ??= Date.now()
|
|
57
|
-
n.id ??= crypto.randomUUID()
|
|
58
|
-
|
|
59
|
-
if (withTimeout) {
|
|
60
|
-
setTimeout(() => removeNotification(n.id), 5000)
|
|
61
|
-
}
|
|
62
|
-
})
|
|
63
|
-
|
|
64
|
-
setNotificationsState(curr =>
|
|
65
|
-
uniqBy(
|
|
66
|
-
// It's ok to cast this now as we know missing properties will have been added above
|
|
67
|
-
[...(data as NotificationData[]), ...curr].sort((a, b) => a.timestamp - b.timestamp),
|
|
68
|
-
"id",
|
|
69
|
-
),
|
|
70
|
-
)
|
|
71
|
-
},
|
|
72
|
-
[removeNotification],
|
|
73
|
-
)
|
|
74
|
-
|
|
75
|
-
return (
|
|
76
|
-
<NotificationsContext.Provider
|
|
77
|
-
value={{
|
|
78
|
-
notifications: notificationsState,
|
|
79
|
-
addNotification,
|
|
80
|
-
removeNotification,
|
|
81
|
-
}}
|
|
82
|
-
>
|
|
83
|
-
{children}
|
|
84
|
-
</NotificationsContext.Provider>
|
|
85
|
-
)
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
const useNotifications = () => use(NotificationsContext)
|
|
89
|
-
|
|
90
|
-
export { NotificationsContext, NotificationsProvider, useNotifications }
|
|
@@ -1,234 +0,0 @@
|
|
|
1
|
-
import React from "react"
|
|
2
|
-
|
|
3
|
-
// Components
|
|
4
|
-
import Select, { type SelectProps } from "./Select"
|
|
5
|
-
|
|
6
|
-
// Types
|
|
7
|
-
import type { Meta, StoryFn } from "@storybook/react-webpack5"
|
|
8
|
-
import { TEXT_FIELD_SIZES, TEXT_FIELD_VARIANTS } from "../TextField"
|
|
9
|
-
|
|
10
|
-
// Utils
|
|
11
|
-
import { DummyPhoneIcon } from "../../../.storybook/components"
|
|
12
|
-
|
|
13
|
-
/*
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
*/
|
|
19
|
-
|
|
20
|
-
const meta: Meta<SelectProps> = {
|
|
21
|
-
title: "Components/Select",
|
|
22
|
-
component: Select,
|
|
23
|
-
parameters: {
|
|
24
|
-
docs: {
|
|
25
|
-
description: {
|
|
26
|
-
component: "A labelled select field with optional leading icon and error state.",
|
|
27
|
-
},
|
|
28
|
-
},
|
|
29
|
-
controls: {
|
|
30
|
-
exclude: ["className", "ref", "children"],
|
|
31
|
-
},
|
|
32
|
-
},
|
|
33
|
-
argTypes: {
|
|
34
|
-
label: {
|
|
35
|
-
type: "string",
|
|
36
|
-
description: "Visible label rendered above the select.",
|
|
37
|
-
table: {
|
|
38
|
-
type: { summary: "string" },
|
|
39
|
-
},
|
|
40
|
-
},
|
|
41
|
-
size: {
|
|
42
|
-
type: "string",
|
|
43
|
-
description: "Determines the size of the select field.",
|
|
44
|
-
table: {
|
|
45
|
-
type: { summary: TEXT_FIELD_SIZES.map(size => `"${size}"`).join(" | ") },
|
|
46
|
-
defaultValue: { summary: '"md"' },
|
|
47
|
-
},
|
|
48
|
-
options: TEXT_FIELD_SIZES,
|
|
49
|
-
control: { type: "select" },
|
|
50
|
-
},
|
|
51
|
-
variant: {
|
|
52
|
-
type: "string",
|
|
53
|
-
description: "Determines the color scheme of the select.",
|
|
54
|
-
table: {
|
|
55
|
-
type: { summary: TEXT_FIELD_VARIANTS.map(variant => `"${variant}"`).join(" | ") },
|
|
56
|
-
defaultValue: { summary: '"dark"' },
|
|
57
|
-
},
|
|
58
|
-
options: TEXT_FIELD_VARIANTS,
|
|
59
|
-
control: { type: "select" },
|
|
60
|
-
},
|
|
61
|
-
placeholder: {
|
|
62
|
-
type: "string",
|
|
63
|
-
description: "Renders a disabled placeholder option shown before a value is selected.",
|
|
64
|
-
table: {
|
|
65
|
-
type: { summary: "string" },
|
|
66
|
-
defaultValue: { summary: "undefined" },
|
|
67
|
-
},
|
|
68
|
-
},
|
|
69
|
-
showOptional: {
|
|
70
|
-
type: "boolean",
|
|
71
|
-
description: 'Shows an "Optional" tag next to the label when the field is not required.',
|
|
72
|
-
table: {
|
|
73
|
-
type: { summary: "boolean" },
|
|
74
|
-
defaultValue: { summary: "true" },
|
|
75
|
-
},
|
|
76
|
-
},
|
|
77
|
-
required: {
|
|
78
|
-
type: "boolean",
|
|
79
|
-
description: 'Marks the field as required and hides the "Optional" tag.',
|
|
80
|
-
table: {
|
|
81
|
-
type: { summary: "boolean" },
|
|
82
|
-
defaultValue: { summary: "false" },
|
|
83
|
-
},
|
|
84
|
-
},
|
|
85
|
-
disabled: {
|
|
86
|
-
type: "boolean",
|
|
87
|
-
description: "Disables the select.",
|
|
88
|
-
table: {
|
|
89
|
-
type: { summary: "boolean" },
|
|
90
|
-
defaultValue: { summary: "false" },
|
|
91
|
-
},
|
|
92
|
-
},
|
|
93
|
-
leadingIcon: {
|
|
94
|
-
description: "Renders an icon inside the field, aligned to the left.",
|
|
95
|
-
table: {
|
|
96
|
-
type: { summary: "{ icon: ReactNode }" },
|
|
97
|
-
defaultValue: { summary: "undefined" },
|
|
98
|
-
},
|
|
99
|
-
},
|
|
100
|
-
error: {
|
|
101
|
-
description: "Renders the field in an error state and displays the provided message.",
|
|
102
|
-
table: {
|
|
103
|
-
type: { summary: "{ message: string }" },
|
|
104
|
-
defaultValue: { summary: "undefined" },
|
|
105
|
-
},
|
|
106
|
-
},
|
|
107
|
-
},
|
|
108
|
-
args: {
|
|
109
|
-
id: "select",
|
|
110
|
-
label: "Label",
|
|
111
|
-
showOptional: true,
|
|
112
|
-
required: false,
|
|
113
|
-
disabled: false,
|
|
114
|
-
size: "md",
|
|
115
|
-
},
|
|
116
|
-
decorators: [
|
|
117
|
-
Story => (
|
|
118
|
-
<div className="w-80">
|
|
119
|
-
<Story />
|
|
120
|
-
</div>
|
|
121
|
-
),
|
|
122
|
-
],
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
const SampleOptions = () => (
|
|
126
|
-
<>
|
|
127
|
-
<option value="apple">Apple</option>
|
|
128
|
-
<option value="banana">Banana</option>
|
|
129
|
-
<option value="cherry">Cherry</option>
|
|
130
|
-
<option value="date">Date</option>
|
|
131
|
-
</>
|
|
132
|
-
)
|
|
133
|
-
|
|
134
|
-
const Template: StoryFn<SelectProps> = args => (
|
|
135
|
-
<Select {...args}>
|
|
136
|
-
<SampleOptions />
|
|
137
|
-
</Select>
|
|
138
|
-
)
|
|
139
|
-
|
|
140
|
-
const LeadingIconTemplate: StoryFn<SelectProps> = args => (
|
|
141
|
-
<Select {...args} leadingIcon={{ icon: <DummyPhoneIcon className="size-5" /> }}>
|
|
142
|
-
<SampleOptions />
|
|
143
|
-
</Select>
|
|
144
|
-
)
|
|
145
|
-
|
|
146
|
-
const Default = Template.bind({})
|
|
147
|
-
const WithPlaceholder = Template.bind({})
|
|
148
|
-
const WithLeadingIcon = LeadingIconTemplate.bind({})
|
|
149
|
-
const Small = Template.bind({})
|
|
150
|
-
const Required = Template.bind({})
|
|
151
|
-
const WithError = Template.bind({})
|
|
152
|
-
const Disabled = Template.bind({})
|
|
153
|
-
|
|
154
|
-
// Args
|
|
155
|
-
Default.args = {}
|
|
156
|
-
|
|
157
|
-
WithPlaceholder.args = {
|
|
158
|
-
placeholder: "Select a fruit…",
|
|
159
|
-
}
|
|
160
|
-
|
|
161
|
-
WithLeadingIcon.args = {
|
|
162
|
-
placeholder: "Select a fruit…",
|
|
163
|
-
}
|
|
164
|
-
|
|
165
|
-
Small.args = {
|
|
166
|
-
size: "sm",
|
|
167
|
-
placeholder: "Select a fruit…",
|
|
168
|
-
}
|
|
169
|
-
|
|
170
|
-
Required.args = {
|
|
171
|
-
required: true,
|
|
172
|
-
placeholder: "Select a fruit…",
|
|
173
|
-
}
|
|
174
|
-
|
|
175
|
-
WithError.args = {
|
|
176
|
-
error: { message: "Please select an option." },
|
|
177
|
-
}
|
|
178
|
-
|
|
179
|
-
Disabled.args = {
|
|
180
|
-
disabled: true,
|
|
181
|
-
placeholder: "Select a fruit…",
|
|
182
|
-
}
|
|
183
|
-
|
|
184
|
-
// Parameters
|
|
185
|
-
WithPlaceholder.parameters = {
|
|
186
|
-
docs: {
|
|
187
|
-
description: {
|
|
188
|
-
story: "The `placeholder` prop renders a disabled option shown before a value is selected.",
|
|
189
|
-
},
|
|
190
|
-
},
|
|
191
|
-
}
|
|
192
|
-
|
|
193
|
-
WithLeadingIcon.parameters = {
|
|
194
|
-
docs: {
|
|
195
|
-
description: {
|
|
196
|
-
story: "The `leadingIcon` prop renders an icon inside the field, aligned to the left.",
|
|
197
|
-
},
|
|
198
|
-
},
|
|
199
|
-
}
|
|
200
|
-
|
|
201
|
-
Small.parameters = {
|
|
202
|
-
docs: {
|
|
203
|
-
description: {
|
|
204
|
-
story: 'Setting `size="sm"` renders a more compact version of the select field.',
|
|
205
|
-
},
|
|
206
|
-
},
|
|
207
|
-
}
|
|
208
|
-
|
|
209
|
-
Required.parameters = {
|
|
210
|
-
docs: {
|
|
211
|
-
description: {
|
|
212
|
-
story: 'Setting `required` hides the "Optional" tag and marks the select as required.',
|
|
213
|
-
},
|
|
214
|
-
},
|
|
215
|
-
}
|
|
216
|
-
|
|
217
|
-
WithError.parameters = {
|
|
218
|
-
docs: {
|
|
219
|
-
description: {
|
|
220
|
-
story: "Pass an `error` object with a `message` string to display an inline error.",
|
|
221
|
-
},
|
|
222
|
-
},
|
|
223
|
-
}
|
|
224
|
-
|
|
225
|
-
Disabled.parameters = {
|
|
226
|
-
docs: {
|
|
227
|
-
description: {
|
|
228
|
-
story: "Setting `disabled` prevents interaction and visually dims the field.",
|
|
229
|
-
},
|
|
230
|
-
},
|
|
231
|
-
}
|
|
232
|
-
|
|
233
|
-
export { Default, WithPlaceholder, WithLeadingIcon, Small, Required, WithError, Disabled }
|
|
234
|
-
export default meta
|
|
@@ -1,129 +0,0 @@
|
|
|
1
|
-
"use client"
|
|
2
|
-
|
|
3
|
-
import React from "react"
|
|
4
|
-
|
|
5
|
-
// Components
|
|
6
|
-
import { ChevronDownIcon } from "@heroicons/react/20/solid"
|
|
7
|
-
import { Container, ErrorMessage, Icon, Label, useInputKeyboardFocus } from "../TextField"
|
|
8
|
-
|
|
9
|
-
// Types
|
|
10
|
-
import type { SelectSize, SelectVariant } from "./types"
|
|
11
|
-
|
|
12
|
-
// Utils
|
|
13
|
-
import clsx from "clsx"
|
|
14
|
-
|
|
15
|
-
// Params
|
|
16
|
-
interface SelectProps extends Omit<React.SelectHTMLAttributes<HTMLSelectElement>, "id" | "size"> {
|
|
17
|
-
id: string
|
|
18
|
-
label?: string
|
|
19
|
-
size?: SelectSize
|
|
20
|
-
variant?: SelectVariant
|
|
21
|
-
leadingIcon?: { icon: React.ReactNode }
|
|
22
|
-
placeholder?: string
|
|
23
|
-
showOptional?: boolean
|
|
24
|
-
error?: {
|
|
25
|
-
message: string
|
|
26
|
-
}
|
|
27
|
-
children: React.ReactNode
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
/*
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
*/
|
|
36
|
-
|
|
37
|
-
const Select: React.FC<SelectProps> = ({
|
|
38
|
-
id,
|
|
39
|
-
label,
|
|
40
|
-
size = "md",
|
|
41
|
-
variant = "dark",
|
|
42
|
-
error,
|
|
43
|
-
leadingIcon,
|
|
44
|
-
placeholder,
|
|
45
|
-
showOptional = true,
|
|
46
|
-
className,
|
|
47
|
-
required,
|
|
48
|
-
disabled,
|
|
49
|
-
onFocus,
|
|
50
|
-
onBlur,
|
|
51
|
-
defaultValue,
|
|
52
|
-
children,
|
|
53
|
-
...rest
|
|
54
|
-
}) => {
|
|
55
|
-
const { keyboardFocused, handleMouseDown, handleMouseUp, handleFocus, handleBlur } =
|
|
56
|
-
useInputKeyboardFocus({ onFocus, onBlur })
|
|
57
|
-
|
|
58
|
-
return (
|
|
59
|
-
<div className={className}>
|
|
60
|
-
<Container
|
|
61
|
-
keyboardFocused={keyboardFocused}
|
|
62
|
-
onMouseDown={handleMouseDown}
|
|
63
|
-
onMouseUp={handleMouseUp}
|
|
64
|
-
size={size}
|
|
65
|
-
hasButton={false}
|
|
66
|
-
label={label}
|
|
67
|
-
showOptional={showOptional}
|
|
68
|
-
required={required}
|
|
69
|
-
variant={variant}
|
|
70
|
-
>
|
|
71
|
-
{label && (
|
|
72
|
-
<Label
|
|
73
|
-
inputId={id}
|
|
74
|
-
label={label}
|
|
75
|
-
showOptional={showOptional}
|
|
76
|
-
required={required}
|
|
77
|
-
variant={variant}
|
|
78
|
-
/>
|
|
79
|
-
)}
|
|
80
|
-
|
|
81
|
-
{leadingIcon?.icon && (
|
|
82
|
-
<Icon position="leading" disabled={disabled} fieldSize={size} variant={variant}>
|
|
83
|
-
{leadingIcon.icon}
|
|
84
|
-
</Icon>
|
|
85
|
-
)}
|
|
86
|
-
|
|
87
|
-
<select
|
|
88
|
-
id={id}
|
|
89
|
-
className={clsx(
|
|
90
|
-
"h-full min-w-0 grow appearance-none bg-transparent focus:outline-hidden has-[option[value='']:checked]:text-neutral-30",
|
|
91
|
-
variant === "dark" && "text-neutral-100",
|
|
92
|
-
variant === "light" && "text-white",
|
|
93
|
-
size === "sm" && ["min-h-6 text-sm", !!leadingIcon?.icon ? "pl-10" : "pl-3", "pr-10"],
|
|
94
|
-
size === "md" && ["min-h-12 text-base", !!leadingIcon?.icon ? "pl-12" : "pl-5", "pr-0"],
|
|
95
|
-
)}
|
|
96
|
-
aria-describedby={error ? `${id}-error` : undefined}
|
|
97
|
-
aria-invalid={!!error}
|
|
98
|
-
required={required}
|
|
99
|
-
onFocus={handleFocus}
|
|
100
|
-
onBlur={handleBlur}
|
|
101
|
-
disabled={disabled}
|
|
102
|
-
defaultValue={defaultValue || placeholder ? "" : undefined}
|
|
103
|
-
{...rest}
|
|
104
|
-
>
|
|
105
|
-
{placeholder && (
|
|
106
|
-
<option value="" disabled hidden>
|
|
107
|
-
{placeholder}
|
|
108
|
-
</option>
|
|
109
|
-
)}
|
|
110
|
-
{children}
|
|
111
|
-
</select>
|
|
112
|
-
|
|
113
|
-
<Icon
|
|
114
|
-
position="trailing"
|
|
115
|
-
disabled={disabled}
|
|
116
|
-
fieldSize={size}
|
|
117
|
-
variant={variant}
|
|
118
|
-
className="pointer-events-none"
|
|
119
|
-
>
|
|
120
|
-
<ChevronDownIcon className="size-5" />
|
|
121
|
-
</Icon>
|
|
122
|
-
</Container>
|
|
123
|
-
{error && <ErrorMessage id={id} error={error} />}
|
|
124
|
-
</div>
|
|
125
|
-
)
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
export default Select
|
|
129
|
-
export type { SelectProps }
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export type { TextFieldSize as SelectSize, TextFieldVariant as SelectVariant } from "../TextField"
|
|
@@ -1,55 +0,0 @@
|
|
|
1
|
-
import React from "react"
|
|
2
|
-
|
|
3
|
-
// Components
|
|
4
|
-
import Spinner from "./Spinner"
|
|
5
|
-
|
|
6
|
-
// Types
|
|
7
|
-
import type { StoryFn, Meta } from "@storybook/react-webpack5"
|
|
8
|
-
import type { SpinnerProps } from "."
|
|
9
|
-
|
|
10
|
-
/*
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
*/
|
|
16
|
-
|
|
17
|
-
const meta: Meta<typeof Spinner> = {
|
|
18
|
-
title: "Components/Spinner",
|
|
19
|
-
component: Spinner,
|
|
20
|
-
parameters: {
|
|
21
|
-
docs: {
|
|
22
|
-
description: {
|
|
23
|
-
component: "A spinner component to indicate loading.",
|
|
24
|
-
},
|
|
25
|
-
},
|
|
26
|
-
},
|
|
27
|
-
argTypes: {
|
|
28
|
-
size: {
|
|
29
|
-
type: "string",
|
|
30
|
-
description: "Size of the spinner.",
|
|
31
|
-
table: {
|
|
32
|
-
type: {
|
|
33
|
-
summary: '"xs" | "sm" | "md" | "lg"',
|
|
34
|
-
},
|
|
35
|
-
defaultValue: {
|
|
36
|
-
summary: '"md"',
|
|
37
|
-
},
|
|
38
|
-
},
|
|
39
|
-
options: ["xs", "sm", "md", "lg"],
|
|
40
|
-
control: { type: "select" },
|
|
41
|
-
},
|
|
42
|
-
},
|
|
43
|
-
args: {
|
|
44
|
-
size: "md",
|
|
45
|
-
},
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
// Templates
|
|
49
|
-
const Template: StoryFn<SpinnerProps> = args => <Spinner {...args} />
|
|
50
|
-
|
|
51
|
-
// Stories
|
|
52
|
-
const Default = Template.bind({})
|
|
53
|
-
|
|
54
|
-
export { Default }
|
|
55
|
-
export default meta
|
|
@@ -1,48 +0,0 @@
|
|
|
1
|
-
import React from "react"
|
|
2
|
-
|
|
3
|
-
// Types
|
|
4
|
-
import type { SpinnerSize } from "./types"
|
|
5
|
-
|
|
6
|
-
// Utils
|
|
7
|
-
import { clsx } from "clsx"
|
|
8
|
-
|
|
9
|
-
// Props
|
|
10
|
-
export interface SpinnerProps extends Omit<React.ComponentProps<"div">, "color"> {
|
|
11
|
-
/** Size of the spinner. */
|
|
12
|
-
size?: SpinnerSize
|
|
13
|
-
}
|
|
14
|
-
/*
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
*/
|
|
20
|
-
|
|
21
|
-
const Spinner: React.FC<SpinnerProps> = ({ className, size = "md", ref, ...rest }) => {
|
|
22
|
-
return (
|
|
23
|
-
<div
|
|
24
|
-
className={clsx(
|
|
25
|
-
{
|
|
26
|
-
xs: "[--spinner-size:1rem]",
|
|
27
|
-
sm: "[--spinner-size:1.5rem]",
|
|
28
|
-
md: "[--spinner-size:2rem]",
|
|
29
|
-
lg: "[--spinner-size:3rem]",
|
|
30
|
-
}[size],
|
|
31
|
-
"relative box-border size-(--spinner-size) shrink-0 grow-0 animate-spin-outer",
|
|
32
|
-
className,
|
|
33
|
-
)}
|
|
34
|
-
ref={ref}
|
|
35
|
-
role="status"
|
|
36
|
-
{...rest}
|
|
37
|
-
>
|
|
38
|
-
<span
|
|
39
|
-
className={clsx(
|
|
40
|
-
"absolute inset-0 m-auto block size-full animate-spin-inner [clip:rect(0,var(--spinner-size),var(--spinner-size),calc(var(--spinner-size)/2))] after:absolute after:inset-0 after:m-auto after:size-full after:animate-spin-after after:rounded-full after:border-[clamp(0.125rem,var(--spinner-size)/10,0.325rem)] after:border-solid after:border-current after:[clip:inherit]",
|
|
41
|
-
)}
|
|
42
|
-
/>
|
|
43
|
-
</div>
|
|
44
|
-
)
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
Spinner.displayName = "Spinner"
|
|
48
|
-
export default Spinner
|