@glyphui/ui 0.2.0 → 0.4.0

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.
Files changed (116) hide show
  1. package/README.md +65 -12
  2. package/dist/chart.d.ts +202 -0
  3. package/dist/chart.js +466 -0
  4. package/dist/color-mode-script-Bf7LYkOj.js +13 -0
  5. package/dist/color-mode-script-KdwItKN2.d.ts +16 -0
  6. package/dist/data-table.js +3 -2
  7. package/dist/{field-CCecIzdq.js → field-CVbywksE.js} +21 -5
  8. package/dist/{field-context-B6WOcK5m.js → field-context-7I-cWvvS.js} +3 -57
  9. package/dist/form.d.ts +11 -4
  10. package/dist/form.js +34 -8
  11. package/dist/glyph-context-DxGJrdvr.d.ts +50 -0
  12. package/dist/{index-BWK4czIG.d.ts → index-Bi7rZ6ba.d.ts} +11 -0
  13. package/dist/index.d.ts +2334 -283
  14. package/dist/index.js +2952 -326
  15. package/dist/react-router.d.ts +18 -0
  16. package/dist/react-router.js +44 -0
  17. package/dist/{states-Rp8wZ_jH.js → states-IvhjBgna.js} +2 -1
  18. package/dist/tv-DLbT66dC.js +70 -0
  19. package/dist/vite.d.ts +27 -0
  20. package/dist/vite.js +29 -0
  21. package/fonts.css +10 -0
  22. package/package.json +47 -5
  23. package/src/components/accordion/accordion.styles.ts +4 -4
  24. package/src/components/badge/badge.styles.ts +11 -16
  25. package/src/components/banner/banner.styles.ts +4 -4
  26. package/src/components/button/button.styles.ts +3 -1
  27. package/src/components/calendar/calendar.styles.ts +51 -0
  28. package/src/components/calendar/calendar.tsx +84 -0
  29. package/src/components/calendar/index.ts +3 -0
  30. package/src/components/carousel/carousel.styles.ts +43 -0
  31. package/src/components/carousel/carousel.tsx +278 -0
  32. package/src/components/carousel/index.ts +13 -0
  33. package/src/components/collapsible/collapsible.tsx +66 -0
  34. package/src/components/collapsible/index.ts +6 -0
  35. package/src/components/context-menu/context-menu.styles.ts +19 -0
  36. package/src/components/context-menu/context-menu.tsx +226 -0
  37. package/src/components/context-menu/index.ts +19 -0
  38. package/src/components/copy-button/copy-button.tsx +117 -0
  39. package/src/components/copy-button/index.ts +1 -0
  40. package/src/components/date-picker/date-picker.styles.ts +42 -0
  41. package/src/components/date-picker/date-picker.tsx +322 -0
  42. package/src/components/date-picker/index.ts +8 -0
  43. package/src/components/dropdown-menu/dropdown-menu.styles.ts +2 -2
  44. package/src/components/eyebrow/eyebrow.styles.ts +1 -1
  45. package/src/components/field/field-context.ts +2 -0
  46. package/src/components/field/field.styles.ts +4 -2
  47. package/src/components/field/field.tsx +25 -4
  48. package/src/components/file-upload/file-upload.styles.ts +43 -0
  49. package/src/components/file-upload/file-upload.tsx +343 -0
  50. package/src/components/file-upload/index.ts +10 -0
  51. package/src/components/hover-card/hover-card.tsx +41 -0
  52. package/src/components/hover-card/index.ts +1 -0
  53. package/src/components/input-otp/index.ts +10 -0
  54. package/src/components/input-otp/input-otp.styles.ts +38 -0
  55. package/src/components/input-otp/input-otp.tsx +116 -0
  56. package/src/components/link/link.styles.ts +1 -1
  57. package/src/components/modal/index.ts +2 -0
  58. package/src/components/modal/modal.styles.ts +20 -0
  59. package/src/components/modal/modal.tsx +111 -0
  60. package/src/components/navigation-menu/index.ts +14 -0
  61. package/src/components/navigation-menu/navigation-menu.styles.ts +48 -0
  62. package/src/components/navigation-menu/navigation-menu.tsx +208 -0
  63. package/src/components/number-input/index.ts +2 -0
  64. package/src/components/number-input/number-input.styles.ts +41 -0
  65. package/src/components/number-input/number-input.tsx +211 -0
  66. package/src/components/password-input/index.ts +7 -0
  67. package/src/components/password-input/password-input.styles.ts +30 -0
  68. package/src/components/password-input/password-input.tsx +127 -0
  69. package/src/components/prose/prose.tsx +1 -1
  70. package/src/components/resizable/index.ts +9 -0
  71. package/src/components/resizable/resizable.styles.ts +28 -0
  72. package/src/components/resizable/resizable.tsx +69 -0
  73. package/src/components/scroll-area/scroll-area.tsx +23 -1
  74. package/src/components/segmented-control/segmented-control.tsx +17 -2
  75. package/src/components/sheet/sheet.styles.ts +7 -7
  76. package/src/components/slider/slider.tsx +9 -2
  77. package/src/components/stepper/index.ts +2 -0
  78. package/src/components/stepper/stepper.styles.ts +74 -0
  79. package/src/components/stepper/stepper.tsx +138 -0
  80. package/src/components/tag-input/index.ts +2 -0
  81. package/src/components/tag-input/tag-input.styles.ts +39 -0
  82. package/src/components/tag-input/tag-input.tsx +198 -0
  83. package/src/components/text/text.styles.ts +4 -4
  84. package/src/components/timeline/index.ts +8 -0
  85. package/src/components/timeline/timeline.styles.ts +56 -0
  86. package/src/components/timeline/timeline.tsx +91 -0
  87. package/src/components/toggle/index.ts +9 -0
  88. package/src/components/toggle/toggle.styles.ts +39 -0
  89. package/src/components/toggle/toggle.tsx +61 -0
  90. package/src/components/tree-view/index.ts +2 -0
  91. package/src/components/tree-view/tree-view.styles.ts +42 -0
  92. package/src/components/tree-view/tree-view.tsx +274 -0
  93. package/src/components/visually-hidden/index.ts +1 -0
  94. package/src/components/visually-hidden/visually-hidden.tsx +10 -0
  95. package/src/index.ts +20 -0
  96. package/src/integrations/react-router.tsx +39 -0
  97. package/src/integrations/vite.test-d.ts +6 -0
  98. package/src/integrations/vite.test.ts +28 -0
  99. package/src/integrations/vite.ts +33 -0
  100. package/src/internal/dev.ts +12 -0
  101. package/src/patterns/app-shell/app-shell.styles.ts +1 -1
  102. package/src/patterns/app-shell/navbar.tsx +34 -16
  103. package/src/patterns/app-shell/sidebar.tsx +7 -2
  104. package/src/patterns/chart/chart-parts.tsx +179 -0
  105. package/src/patterns/chart/chart.styles.ts +35 -0
  106. package/src/patterns/chart/chart.tsx +386 -0
  107. package/src/patterns/chart/index.ts +13 -0
  108. package/src/patterns/form/form.tsx +48 -6
  109. package/src/patterns/form/index.ts +1 -0
  110. package/src/provider/color-mode-script.ts +28 -0
  111. package/src/provider/color-mode.tsx +14 -20
  112. package/src/provider/glyph-context.ts +38 -0
  113. package/src/provider/glyph-provider.tsx +16 -4
  114. package/src/provider/index.ts +4 -0
  115. package/src/provider/theme-scope.tsx +7 -3
  116. package/styles.css +88 -0
package/dist/form.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { i as ButtonProps, n as FieldProps } from "./index-BWK4czIG.js";
1
+ import { i as ButtonProps, n as FieldProps } from "./index-Bi7rZ6ba.js";
2
2
  import { ComponentProps, ReactNode } from "react";
3
3
  import { Control, ControllerRenderProps, FieldPath, FieldValues, UseFormProps, UseFormReturn } from "react-hook-form";
4
4
  import { StandardSchemaV1 } from "@standard-schema/spec";
@@ -28,7 +28,7 @@ interface FormProps<TInput extends FieldValues, TOutput> extends Omit<ComponentP
28
28
  */
29
29
  onSubmit: (values: TOutput) => SubmitResult<TInput> | Promise<SubmitResult<TInput>>;
30
30
  }
31
- export declare function Form<TInput extends FieldValues, TOutput>({ form, onSubmit, children, ...props }: FormProps<TInput, TOutput>): import("react").JSX.Element;
31
+ export declare function Form<TInput extends FieldValues, TOutput>({ form, onSubmit, children, ref, ...props }: FormProps<TInput, TOutput>): import("react").JSX.Element;
32
32
  interface FormFieldProps<TInput extends FieldValues, TName extends FieldPath<TInput>> extends Omit<FieldProps, 'children' | 'error'> {
33
33
  control: Control<TInput, unknown, any>;
34
34
  /** Typed from the schema: a misspelled name is a compile error. */
@@ -38,8 +38,15 @@ interface FormFieldProps<TInput extends FieldValues, TName extends FieldPath<TIn
38
38
  }
39
39
  /** One schema field: label, control, description and validation message, all wired. */
40
40
  export declare function FormField<TInput extends FieldValues, TName extends FieldPath<TInput>>({ control, name, children, ...fieldProps }: FormFieldProps<TInput, TName>): import("react").JSX.Element;
41
+ interface FormSubmitProps extends Omit<ButtonProps, 'type' | 'form'> {
42
+ /**
43
+ * The form to submit, for a button outside `<Form>` such as a Modal footer:
44
+ * `<FormSubmit form={form}>`. Not needed inside `<Form>`.
45
+ */
46
+ form?: UseFormReturn<any, any, any>;
47
+ }
41
48
  /** Submit button that shows progress while the form submits. */
42
- export declare function FormSubmit(props: Omit<ButtonProps, 'type'>): import("react").JSX.Element;
49
+ export declare function FormSubmit({ form, onClick, ...props }: FormSubmitProps): import("react").JSX.Element;
43
50
  export declare const formErrorStyles: import("tailwind-variants").TVReturnType<{
44
51
  [key: string]: {
45
52
  [key: string]: import("tailwind-variants").ClassValue | {
@@ -76,4 +83,4 @@ export declare function FormError({ className }: {
76
83
  className?: string;
77
84
  }): import("react").JSX.Element | null;
78
85
  //#endregion
79
- export type { FormErrors, FormFieldProps, FormProps, SubmitResult, UseFormOptions };
86
+ export type { FormErrors, FormFieldProps, FormProps, FormSubmitProps, SubmitResult, UseFormOptions };
package/dist/form.js CHANGED
@@ -1,9 +1,11 @@
1
1
  "use client";
2
- import { c as tv, m as AlertIcon, r as Button } from "./field-context-B6WOcK5m.js";
3
- import { t as Field } from "./field-CCecIzdq.js";
2
+ import { t as tv } from "./tv-DLbT66dC.js";
3
+ import { c as AlertIcon, r as Button } from "./field-context-7I-cWvvS.js";
4
+ import { t as Field } from "./field-CVbywksE.js";
5
+ import { useCallback } from "react";
4
6
  import { jsx, jsxs } from "react/jsx-runtime";
5
7
  import { standardSchemaResolver } from "@hookform/resolvers/standard-schema";
6
- import { Controller, FormProvider, useForm as useForm$1, useFormState } from "react-hook-form";
8
+ import { Controller, FormProvider, useForm as useForm$1, useFormContext, useFormState } from "react-hook-form";
7
9
  //#region src/patterns/form/form.tsx
8
10
  /**
9
11
  * react-hook-form's `useForm`, validated by a schema. Field names and submitted values are
@@ -16,7 +18,16 @@ function useForm({ schema, ...options }) {
16
18
  resolver: standardSchemaResolver(schema)
17
19
  });
18
20
  }
19
- function Form({ form, onSubmit, children, ...props }) {
21
+ /** The rendered `<form>` of each form, so a FormSubmit outside it can submit it. */
22
+ const formElements = /* @__PURE__ */ new WeakMap();
23
+ function Form({ form, onSubmit, children, ref, ...props }) {
24
+ const control = form.control;
25
+ const registerElement = useCallback((element) => {
26
+ if (element) formElements.set(control, element);
27
+ else formElements.delete(control);
28
+ if (typeof ref === "function") ref(element);
29
+ else if (ref) ref.current = element;
30
+ }, [control, ref]);
20
31
  const submit = form.handleSubmit(async (values) => {
21
32
  try {
22
33
  const result = await onSubmit(values);
@@ -37,6 +48,7 @@ function Form({ form, onSubmit, children, ...props }) {
37
48
  children: /* @__PURE__ */ jsx("form", {
38
49
  noValidate: true,
39
50
  onSubmit: submit,
51
+ ref: registerElement,
40
52
  ...props,
41
53
  children
42
54
  })
@@ -55,16 +67,30 @@ function FormField({ control, name, children, ...fieldProps }) {
55
67
  });
56
68
  }
57
69
  /** Submit button that shows progress while the form submits. */
58
- function FormSubmit(props) {
59
- const { isSubmitting } = useFormState();
60
- return /* @__PURE__ */ jsx(Button, {
70
+ function FormSubmit({ form, onClick, ...props }) {
71
+ const context = useFormContext();
72
+ const control = (form ?? context)?.control;
73
+ if (!control) throw new Error("FormSubmit must be inside <Form> or receive form={form}, e.g. <FormSubmit form={form}> in a Modal footer.");
74
+ const { isSubmitting } = useFormState({ control });
75
+ if (!form) return /* @__PURE__ */ jsx(Button, {
61
76
  type: "submit",
62
77
  loading: isSubmitting,
78
+ onClick,
79
+ ...props
80
+ });
81
+ const submitOutside = (event) => {
82
+ onClick?.(event);
83
+ if (!event.defaultPrevented) formElements.get(control)?.requestSubmit();
84
+ };
85
+ return /* @__PURE__ */ jsx(Button, {
86
+ type: "button",
87
+ loading: isSubmitting,
88
+ onClick: submitOutside,
63
89
  ...props
64
90
  });
65
91
  }
66
92
  const formErrorStyles = tv({ slots: {
67
- base: "flex items-start gap-2 rounded-md border border-danger/30 bg-danger/8 px-3 py-2.5 text-small text-danger",
93
+ base: "flex items-start gap-2 rounded-md border border-danger/30 bg-danger/8 px-3 py-2.5 text-small text-danger-text",
68
94
  icon: "mt-0.5 size-4 shrink-0"
69
95
  } });
70
96
  /** Form-level error (thrown from `onSubmit` or returned as `errors.root`). */
@@ -0,0 +1,50 @@
1
+ import { Theme } from "@glyphui/tokens";
2
+ import { ElementType, MouseEventHandler, ReactNode } from "react";
3
+ //#region src/provider/glyph-context.d.ts
4
+ /** Props Glyph passes to your router's link component. */
5
+ interface LinkComponentProps {
6
+ href: string;
7
+ className?: string;
8
+ children?: ReactNode;
9
+ onClick?: MouseEventHandler<HTMLAnchorElement>;
10
+ 'aria-current'?: 'page' | undefined;
11
+ }
12
+ /**
13
+ * Any component that renders a link from these props. Plain `'a'` by default.
14
+ * React Router: `({ href, ...props }) => <Link to={href} {...props} />`
15
+ */
16
+ type LinkComponent = ElementType<LinkComponentProps>;
17
+ interface IsActiveOptions {
18
+ /** Match only this exact path, not its children. Default false. */
19
+ end?: boolean;
20
+ }
21
+ /**
22
+ * A hook that reports whether `href` is the current location. Glyph calls it once per
23
+ * navigation item on every render, so it must follow the rules of hooks.
24
+ */
25
+ type UseIsActive = (href: string, options?: IsActiveOptions) => boolean;
26
+ /** Connects Glyph's navigation components to your router. */
27
+ interface GlyphRouter {
28
+ /** Renders links client-side. */
29
+ Link: LinkComponent;
30
+ /** Marks Sidebar, Navbar and NavigationMenu items active automatically. */
31
+ useIsActive?: UseIsActive;
32
+ }
33
+ interface GlyphContextValue {
34
+ theme: Theme;
35
+ linkComponent: LinkComponent;
36
+ useIsActive: UseIsActive;
37
+ }
38
+ /** The active theme and app-level settings. Must be used under `GlyphProvider`. */
39
+ declare function useGlyph(): GlyphContextValue;
40
+ /** The router-aware link component configured on `GlyphProvider`. */
41
+ declare function useLinkComponent(): LinkComponent;
42
+ /**
43
+ * Whether `href` is the current page, using the router passed to `GlyphProvider`.
44
+ * Returns `explicit` when it is set, so an `active` prop always wins.
45
+ */
46
+ declare function useIsActive(href: string | undefined, options?: IsActiveOptions & {
47
+ explicit?: boolean | undefined;
48
+ }): boolean;
49
+ //#endregion
50
+ export { LinkComponentProps as a, useIsActive as c, LinkComponent as i, useLinkComponent as l, GlyphRouter as n, UseIsActive as o, IsActiveOptions as r, useGlyph as s, GlyphContextValue as t };
@@ -156,6 +156,8 @@ declare const fieldStyles: import("tailwind-variants").TVReturnType<{
156
156
  }, {
157
157
  root: string;
158
158
  label: string;
159
+ labelRow: string;
160
+ labelAction: string;
159
161
  required: string;
160
162
  text: string;
161
163
  description: string;
@@ -170,6 +172,8 @@ declare const fieldStyles: import("tailwind-variants").TVReturnType<{
170
172
  }, {
171
173
  root: string;
172
174
  label: string;
175
+ labelRow: string;
176
+ labelAction: string;
173
177
  required: string;
174
178
  text: string;
175
179
  description: string;
@@ -184,6 +188,8 @@ declare const fieldStyles: import("tailwind-variants").TVReturnType<{
184
188
  }, {
185
189
  root: string;
186
190
  label: string;
191
+ labelRow: string;
192
+ labelAction: string;
187
193
  required: string;
188
194
  text: string;
189
195
  description: string;
@@ -212,6 +218,11 @@ declare function IconButton({ icon, variant, ...props }: IconButtonProps): impor
212
218
  //#region src/components/field/field.d.ts
213
219
  interface FieldProps extends Omit<ComponentProps<'div'>, 'children'>, FieldVariants {
214
220
  label?: ReactNode;
221
+ /**
222
+ * Shown at the end of the label row, outside the label, so it is not part of the
223
+ * control's accessible name. For example a "Forgot password?" link.
224
+ */
225
+ labelAction?: ReactNode;
215
226
  description?: ReactNode;
216
227
  /** Error message. Marks the control invalid and is announced to screen readers. */
217
228
  error?: ReactNode;