@flipdish/ui-library 0.2.1 → 0.2.2
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/README.md +66 -297
- package/dist/hooks/useBreakpoints/index.cjs +39 -0
- package/dist/hooks/useBreakpoints/index.cjs.map +1 -0
- package/dist/hooks/useBreakpoints/index.d.ts +19 -0
- package/dist/hooks/useBreakpoints/index.d.ts.map +1 -0
- package/dist/hooks/useBreakpoints/index.js +37 -0
- package/dist/hooks/useBreakpoints/index.js.map +1 -0
- package/dist/hooks/useClipboard/index.cjs +70 -0
- package/dist/hooks/useClipboard/index.cjs.map +1 -0
- package/dist/hooks/useClipboard/index.d.ts +29 -0
- package/dist/hooks/useClipboard/index.d.ts.map +1 -0
- package/dist/hooks/useClipboard/index.js +68 -0
- package/dist/hooks/useClipboard/index.js.map +1 -0
- package/dist/providers/RouteProvider/index.cjs +16 -0
- package/dist/providers/RouteProvider/index.cjs.map +1 -0
- package/dist/providers/RouteProvider/index.d.ts +12 -0
- package/dist/providers/RouteProvider/index.d.ts.map +1 -0
- package/dist/providers/RouteProvider/index.js +14 -0
- package/dist/providers/RouteProvider/index.js.map +1 -0
- package/dist/providers/ThemeProvider/index.cjs +54 -0
- package/dist/providers/ThemeProvider/index.cjs.map +1 -0
- package/dist/providers/ThemeProvider/index.d.ts +31 -0
- package/dist/providers/ThemeProvider/index.d.ts.map +1 -0
- package/dist/providers/ThemeProvider/index.js +51 -0
- package/dist/providers/ThemeProvider/index.js.map +1 -0
- package/package.json +17 -17
- package/dist/src/components/atoms/Avatar/avatar.utils.d.ts +0 -10
- package/dist/src/components/atoms/Avatar/avatar.utils.d.ts.map +0 -1
- package/dist/src/components/atoms/Avatar/components/avatar-add-button.d.ts +0 -9
- package/dist/src/components/atoms/Avatar/components/avatar-add-button.d.ts.map +0 -1
- package/dist/src/components/atoms/Avatar/components/avatar-company-icon.d.ts +0 -8
- package/dist/src/components/atoms/Avatar/components/avatar-company-icon.d.ts.map +0 -1
- package/dist/src/components/atoms/Avatar/components/avatar-count.d.ts +0 -7
- package/dist/src/components/atoms/Avatar/components/avatar-count.d.ts.map +0 -1
- package/dist/src/components/atoms/Avatar/components/avatar-online-indicator.d.ts +0 -8
- package/dist/src/components/atoms/Avatar/components/avatar-online-indicator.d.ts.map +0 -1
- package/dist/src/components/atoms/Avatar/components/verified-tick.d.ts +0 -7
- package/dist/src/components/atoms/Avatar/components/verified-tick.d.ts.map +0 -1
- package/dist/src/components/atoms/Avatar/index.d.ts +0 -65
- package/dist/src/components/atoms/Avatar/index.d.ts.map +0 -1
- package/dist/src/components/atoms/Badge/badge.types.d.ts +0 -22
- package/dist/src/components/atoms/Badge/badge.types.d.ts.map +0 -1
- package/dist/src/components/atoms/Badge/index.d.ts +0 -129
- package/dist/src/components/atoms/Badge/index.d.ts.map +0 -1
- package/dist/src/components/atoms/Button/index.d.ts +0 -111
- package/dist/src/components/atoms/Button/index.d.ts.map +0 -1
- package/dist/src/components/atoms/Checkbox/index.d.ts +0 -26
- package/dist/src/components/atoms/Checkbox/index.d.ts.map +0 -1
- package/dist/src/components/atoms/Divider/index.d.ts +0 -17
- package/dist/src/components/atoms/Divider/index.d.ts.map +0 -1
- package/dist/src/components/atoms/Dot/index.d.ts +0 -5
- package/dist/src/components/atoms/Dot/index.d.ts.map +0 -1
- package/dist/src/components/atoms/FeaturedIcon/index.d.ts +0 -15
- package/dist/src/components/atoms/FeaturedIcon/index.d.ts.map +0 -1
- package/dist/src/components/atoms/Input/components/hint-text.d.ts +0 -15
- package/dist/src/components/atoms/Input/components/hint-text.d.ts.map +0 -1
- package/dist/src/components/atoms/Input/components/label.d.ts +0 -16
- package/dist/src/components/atoms/Input/components/label.d.ts.map +0 -1
- package/dist/src/components/atoms/Input/index.d.ts +0 -60
- package/dist/src/components/atoms/Input/index.d.ts.map +0 -1
- package/dist/src/components/atoms/LoadingIndicator/index.d.ts +0 -19
- package/dist/src/components/atoms/LoadingIndicator/index.d.ts.map +0 -1
- package/dist/src/components/atoms/RadioButton/index.d.ts +0 -33
- package/dist/src/components/atoms/RadioButton/index.d.ts.map +0 -1
- package/dist/src/components/atoms/Toggle/index.d.ts +0 -21
- package/dist/src/components/atoms/Toggle/index.d.ts.map +0 -1
- package/dist/src/components/atoms/Tooltip/index.d.ts +0 -30
- package/dist/src/components/atoms/Tooltip/index.d.ts.map +0 -1
- package/dist/src/components/molecules/Breadcrumbs/components/breadcrumb-account-item.d.ts +0 -13
- package/dist/src/components/molecules/Breadcrumbs/components/breadcrumb-account-item.d.ts.map +0 -1
- package/dist/src/components/molecules/Breadcrumbs/components/breadcrumb-item.d.ts +0 -19
- package/dist/src/components/molecules/Breadcrumbs/components/breadcrumb-item.d.ts.map +0 -1
- package/dist/src/components/molecules/Breadcrumbs/index.d.ts +0 -25
- package/dist/src/components/molecules/Breadcrumbs/index.d.ts.map +0 -1
- package/dist/src/components/molecules/ButtonGroup/index.d.ts +0 -41
- package/dist/src/components/molecules/ButtonGroup/index.d.ts.map +0 -1
- package/dist/src/components/molecules/Dropdown/index.d.ts +0 -35
- package/dist/src/components/molecules/Dropdown/index.d.ts.map +0 -1
- package/dist/src/components/molecules/RadioGroup/components/radio-group-avatar.d.ts +0 -16
- package/dist/src/components/molecules/RadioGroup/components/radio-group-avatar.d.ts.map +0 -1
- package/dist/src/components/molecules/RadioGroup/components/radio-group-checkbox.d.ts +0 -9
- package/dist/src/components/molecules/RadioGroup/components/radio-group-checkbox.d.ts.map +0 -1
- package/dist/src/components/molecules/RadioGroup/components/radio-group-icon-card.d.ts +0 -21
- package/dist/src/components/molecules/RadioGroup/components/radio-group-icon-card.d.ts.map +0 -1
- package/dist/src/components/molecules/RadioGroup/components/radio-group-icon-simple.d.ts +0 -19
- package/dist/src/components/molecules/RadioGroup/components/radio-group-icon-simple.d.ts.map +0 -1
- package/dist/src/components/molecules/RadioGroup/components/radio-group-payment-icon.d.ts +0 -16
- package/dist/src/components/molecules/RadioGroup/components/radio-group-payment-icon.d.ts.map +0 -1
- package/dist/src/components/molecules/RadioGroup/components/radio-group-radio-button.d.ts +0 -9
- package/dist/src/components/molecules/RadioGroup/components/radio-group-radio-button.d.ts.map +0 -1
- package/dist/src/components/molecules/RadioGroup/index.d.ts +0 -7
- package/dist/src/components/molecules/RadioGroup/index.d.ts.map +0 -1
- package/dist/src/components/molecules/RadioGroup/radioGroup.types.d.ts +0 -12
- package/dist/src/components/molecules/RadioGroup/radioGroup.types.d.ts.map +0 -1
- package/dist/src/components/molecules/SectionHeader/index.d.ts +0 -9
- package/dist/src/components/molecules/SectionHeader/index.d.ts.map +0 -1
- package/dist/src/components/molecules/Select/components/combobox.d.ts +0 -15
- package/dist/src/components/molecules/Select/components/combobox.d.ts.map +0 -1
- package/dist/src/components/molecules/Select/components/popover.d.ts +0 -8
- package/dist/src/components/molecules/Select/components/popover.d.ts.map +0 -1
- package/dist/src/components/molecules/Select/components/select-item.d.ts +0 -11
- package/dist/src/components/molecules/Select/components/select-item.d.ts.map +0 -1
- package/dist/src/components/molecules/Select/components/select-shared.d.ts +0 -59
- package/dist/src/components/molecules/Select/components/select-shared.d.ts.map +0 -1
- package/dist/src/components/molecules/Select/index.d.ts +0 -19
- package/dist/src/components/molecules/Select/index.d.ts.map +0 -1
- package/dist/src/components/organisms/PageHeader/components/page-header-simple.d.ts +0 -24
- package/dist/src/components/organisms/PageHeader/components/page-header-simple.d.ts.map +0 -1
- package/dist/src/components/organisms/PageHeader/index.d.ts +0 -2
- package/dist/src/components/organisms/PageHeader/index.d.ts.map +0 -1
- package/dist/src/components/templates/NotFoundPage/index.d.ts +0 -25
- package/dist/src/components/templates/NotFoundPage/index.d.ts.map +0 -1
- package/dist/src/components/templates/PageLayout/index.d.ts +0 -43
- package/dist/src/components/templates/PageLayout/index.d.ts.map +0 -1
- package/dist/src/hooks/useResizeObserver/index.d.ts +0 -25
- package/dist/src/hooks/useResizeObserver/index.d.ts.map +0 -1
- package/dist/src/providers/ErrorBoundary/index.d.ts +0 -32
- package/dist/src/providers/ErrorBoundary/index.d.ts.map +0 -1
- package/dist/src/utilities/cx/index.d.ts +0 -22
- package/dist/src/utilities/cx/index.d.ts.map +0 -1
- package/dist/src/utilities/isReactComponent/index.d.ts +0 -24
- package/dist/src/utilities/isReactComponent/index.d.ts.map +0 -1
- package/dist/src/utilities/renderUtils/index.d.ts +0 -56
- package/dist/src/utilities/renderUtils/index.d.ts.map +0 -1
package/README.md
CHANGED
|
@@ -1,119 +1,56 @@
|
|
|
1
1
|
# `@flipdish/ui-library`
|
|
2
2
|
|
|
3
|
-
Atomic-design component library for
|
|
4
|
-
|
|
5
|
-
---
|
|
6
|
-
|
|
7
|
-
## TODO: future extraction to a standalone repo
|
|
8
|
-
|
|
9
|
-
This package already uses its final name, `@flipdish/ui-library`. Inside this monorepo it resolves to source via `workspace:*` (no build step); the import paths below are the public API today and stay identical after extraction.
|
|
10
|
-
|
|
11
|
-
**Why call out a future extraction:**
|
|
12
|
-
|
|
13
|
-
- This package is currently one MFE's POC; the published library will be a curated, org-wide system maintained by the design-system team.
|
|
14
|
-
- Keeping the name and import surface stable now means the move to a standalone repo + published npm package is a mechanical change, not an API break.
|
|
15
|
-
|
|
16
|
-
**When to extract:**
|
|
17
|
-
|
|
18
|
-
When the design system team is ready to move this library to its own repo and publish to internal npm. At that point:
|
|
19
|
-
|
|
20
|
-
1. Move source out to a new `flipdish/ui-library` (or equivalent) repo.
|
|
21
|
-
2. Keep `name` in `package.json` as `@flipdish/ui-library` (already set).
|
|
22
|
-
3. Add a build pipeline (Vite/Rollup → `dist/`). Then expand each entry in `exports` from the source-only shorthand:
|
|
23
|
-
```jsonc
|
|
24
|
-
"./atoms/*": "./src/components/atoms/*/index.tsx"
|
|
25
|
-
```
|
|
26
|
-
to the conditional shape used by `@flipdish/portal-library`:
|
|
27
|
-
```jsonc
|
|
28
|
-
"./atoms/*": {
|
|
29
|
-
"types": "./dist/components/atoms/*/index.d.ts",
|
|
30
|
-
"import": "./dist/components/atoms/*/index.js",
|
|
31
|
-
"node": "./dist/components/atoms/*/index.cjs.js"
|
|
32
|
-
}
|
|
33
|
-
```
|
|
34
|
-
The keys (`./atoms/*` etc.) stay identical, so consumer import paths don't change.
|
|
35
|
-
4. Add `tailwindcss`, `@tailwindcss/vite`, `postcss-prefix-selector`, `vite-plugin-css-injected-by-js` to the new repo's `devDependencies` (needed at that point for Storybook + the lib's own build).
|
|
36
|
-
5. In the consuming repo, replace `"@flipdish/ui-library": "workspace:*"` with `"@flipdish/ui-library": "^<version>"`.
|
|
37
|
-
6. Import sites need no changes — the package name and subpaths are unchanged.
|
|
38
|
-
7. Delete `packages/ui-library/` from this repo.
|
|
39
|
-
8. Renovate (already wired in `renovate.json`) auto-updates minor/patch versions thereafter.
|
|
40
|
-
|
|
41
|
-
The rename is a single mechanical PR — the API shape (`peerDependencies`, exports keys, atomic folder structure) stays the same. Naming today is therefore a _placeholder_, not a contract.
|
|
42
|
-
|
|
43
|
-
The same pattern applies to the planned design-tokens package: scaffolded as `@flipdish/ui-tokens` locally, will extract to `@flipdish/ui-tokens` later.
|
|
44
|
-
|
|
45
|
-
---
|
|
46
|
-
|
|
47
|
-
## Layout
|
|
48
|
-
|
|
49
|
-
```text
|
|
50
|
-
src/
|
|
51
|
-
├── styles.css # shared Tailwind runtime (plugins, variants, @utility, base resets) → `@flipdish/ui-library/styles`
|
|
52
|
-
├── components/
|
|
53
|
-
│ ├── atoms/ # paste target — smallest building blocks (Button, Input, Badge …)
|
|
54
|
-
│ ├── molecules/ # paste target — compose atoms (FormField, RadioGroup …)
|
|
55
|
-
│ ├── organisms/ # paste target — compose atoms + molecules (Modal, Toaster …)
|
|
56
|
-
│ └── templates/ # page-shaped layouts (NotFoundPage, PageLayout, MfeShell)
|
|
57
|
-
│ └── NotFoundPage/
|
|
58
|
-
│ ├── index.tsx # component implementation (not a barrel)
|
|
59
|
-
│ └── NotFoundPage.test.tsx # co-located test (greppable name)
|
|
60
|
-
├── providers/ # cross-cutting behavioural wrappers, NOT on the visual atomic ladder (ErrorBoundary …)
|
|
61
|
-
│ └── ErrorBoundary/ # wraps react-error-boundary behind a stable seam → `@flipdish/ui-library/providers/ErrorBoundary`
|
|
62
|
-
│ └── index.tsx
|
|
63
|
-
├── hooks/ # layer-agnostic hooks (useMediaQuery …) — paste target
|
|
64
|
-
├── utilities/ # layer-agnostic helpers
|
|
65
|
-
│ ├── cx/
|
|
66
|
-
│ │ └── index.ts # cx (extendTailwindMerge wrapper) + sortCx — shared, pure JS
|
|
67
|
-
│ └── renderUtils/
|
|
68
|
-
│ ├── index.ts # getMicroFrontendAttribute, lazyWithRetry, getAppId, ... (web-only MFE runtime)
|
|
69
|
-
│ └── renderUtils.test.ts # co-located test (planned)
|
|
70
|
-
```
|
|
3
|
+
Atomic-design React component library for Flipdish products, built on **Tailwind CSS v4**, [Untitled UI](https://www.untitledui.com/) primitives, and [React Aria Components](https://react-spectrum.adobe.com/react-aria/). Web-first today, with React Native (via [NativeWind](https://www.nativewind.dev/)) support rolling out per component.
|
|
71
4
|
|
|
72
|
-
|
|
73
|
-
class-merge helper is `cx`/`sortCx` (Untitled UI naming), living under
|
|
74
|
-
`utilities/` — there is no separate `utils/cn`.
|
|
5
|
+
> **Internal design system, published publicly.** This package is built for and tuned to Flipdish's brand and tooling. It's on the public npm registry so it can be shared across Flipdish micro-frontends and apps — it isn't intended as a general-purpose UI kit.
|
|
75
6
|
|
|
76
|
-
**
|
|
7
|
+
**Part of the Flipdish Design System:**
|
|
77
8
|
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
-
|
|
9
|
+
| Package | Purpose |
|
|
10
|
+
| -------------------------------------------------------------------------- | -------------------------------------------- |
|
|
11
|
+
| [`@flipdish/ui-tokens`](https://www.npmjs.com/package/@flipdish/ui-tokens) | Design tokens — colours, type scale, spacing |
|
|
12
|
+
| [`@flipdish/ui-icons`](https://www.npmjs.com/package/@flipdish/ui-icons) | Icon set |
|
|
13
|
+
| **`@flipdish/ui-library`** | Components (this package) |
|
|
82
14
|
|
|
83
|
-
|
|
15
|
+
## Installation
|
|
84
16
|
|
|
85
|
-
|
|
17
|
+
```bash
|
|
18
|
+
pnpm add @flipdish/ui-library
|
|
19
|
+
```
|
|
86
20
|
|
|
87
|
-
|
|
88
|
-
// Components
|
|
89
|
-
import { Button } from "@flipdish/ui-library/components/atoms/Button";
|
|
90
|
-
import { NotFoundPage } from "@flipdish/ui-library/components/templates/NotFoundPage";
|
|
21
|
+
### Peer dependencies
|
|
91
22
|
|
|
92
|
-
|
|
93
|
-
import { ErrorBoundary } from "@flipdish/ui-library/providers/ErrorBoundary";
|
|
23
|
+
Install the peers for the platform(s) you target. Platform-specific peers are declared `optional`, so a web-only consumer is never warned about the React Native stack (and vice versa).
|
|
94
24
|
|
|
95
|
-
|
|
96
|
-
import { useMediaQuery } from "@flipdish/ui-library/hooks/useMediaQuery";
|
|
25
|
+
**Shared — required on every platform:**
|
|
97
26
|
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
27
|
+
| Package | Version |
|
|
28
|
+
| ------------------- | --------- |
|
|
29
|
+
| `react` | `^19.0.0` |
|
|
30
|
+
| `clsx` | `^2.1.1` |
|
|
31
|
+
| `tailwind-merge` | `^3.6.0` |
|
|
32
|
+
| `tailwind-variants` | `^3.2.2` |
|
|
33
|
+
|
|
34
|
+
**Web:**
|
|
35
|
+
|
|
36
|
+
| Package | Version |
|
|
37
|
+
| ----------------------- | --------- |
|
|
38
|
+
| `react-dom` | `^19.0.0` |
|
|
39
|
+
| `react-aria-components` | `^1.18.0` |
|
|
40
|
+
| `react-router` | `^7.0.0` |
|
|
105
41
|
|
|
106
|
-
|
|
42
|
+
**React Native:**
|
|
107
43
|
|
|
108
|
-
|
|
44
|
+
| Package | Version |
|
|
45
|
+
| --------------------------------- | ---------- |
|
|
46
|
+
| `react-native` | `>=0.79.0` |
|
|
47
|
+
| `nativewind` | `^4.1.0` |
|
|
48
|
+
| `@react-native-aria/interactions` | `>=0.2.7` |
|
|
49
|
+
| `@react-native-aria/focus` | `>=0.2.7` |
|
|
109
50
|
|
|
110
|
-
##
|
|
51
|
+
## Tailwind setup
|
|
111
52
|
|
|
112
|
-
|
|
113
|
-
plugins, custom variants, `@utility` definitions, base resets — plus the `@source`
|
|
114
|
-
that scans this library for class names, is centralised in `src/styles.css` and
|
|
115
|
-
exported as `@flipdish/ui-library/styles`. Consumers import it from their
|
|
116
|
-
Tailwind entry CSS so each MFE/app doesn't re-declare it:
|
|
53
|
+
The library ships a shared Tailwind runtime — plugins, custom variants, `@utility` definitions, and base resets — at `@flipdish/ui-library/styles`. Import it from your Tailwind entry CSS, alongside the tokens, so each app doesn't re-declare it:
|
|
117
54
|
|
|
118
55
|
```css
|
|
119
56
|
@layer theme, base, components, utilities;
|
|
@@ -121,218 +58,50 @@ Tailwind entry CSS so each MFE/app doesn't re-declare it:
|
|
|
121
58
|
@import "tailwindcss/theme.css" layer(theme);
|
|
122
59
|
@import "@flipdish/ui-tokens/css" layer(theme); /* tokens + [data-theme="dark"] */
|
|
123
60
|
@import "tailwindcss/preflight.css" layer(base);
|
|
124
|
-
@import "@flipdish/ui-library/styles"; /* plugins, variants, @utility, resets
|
|
61
|
+
@import "@flipdish/ui-library/styles"; /* plugins, variants, @utility, resets */
|
|
125
62
|
@import "tailwindcss/utilities.css" layer(utilities);
|
|
126
63
|
```
|
|
127
64
|
|
|
128
|
-
|
|
129
|
-
concerns): the `@layer` order, the `tailwindcss` theme/preflight/utilities imports,
|
|
130
|
-
and any PostCSS scoping (e.g. property-service's `#flipdish-micro-frontend` prefix
|
|
131
|
-
pipeline). `styles.css` declares `@plugin`s, so the plugin packages are ui-library
|
|
132
|
-
`dependencies` (see below) — `@plugin` resolves relative to the file declaring it.
|
|
133
|
-
|
|
134
|
-
## Design tokens
|
|
135
|
-
|
|
136
|
-
Tokens (brand colors, type scale, spacing overrides) do **not** live in this package — they live in the separate `@flipdish/ui-tokens` workspace package (also planned for future extraction to `@flipdish/ui-tokens`). See Phase 2.5 of the migration plan.
|
|
137
|
-
|
|
138
|
-
## Dependency conventions
|
|
139
|
-
|
|
140
|
-
Mirrors the `@flipdish/portal-library` shape so the eventual extraction is a clean rename, not a dep-graph restructure.
|
|
141
|
-
|
|
142
|
-
### Runtime deps → `peerDependencies` (with matching `devDependencies` for typecheck)
|
|
143
|
-
|
|
144
|
-
Peers are split into three buckets: **shared** (every consumer needs them, on any
|
|
145
|
-
platform) and two **platform-specific** buckets (`web-only` / `app-only`) that are
|
|
146
|
-
marked `optional` so a consumer is never warned about the other platform's stack.
|
|
147
|
-
|
|
148
|
-
**Shared — required on every platform:**
|
|
149
|
-
|
|
150
|
-
| Package | Why peer | Version |
|
|
151
|
-
| ------------------- | -------------------------------------------------------------------------------------- | --------- |
|
|
152
|
-
| `react` | Hooks need a singleton React; shared by web + RN | `^19.0.0` |
|
|
153
|
-
| `clsx` | Consumer feature code imports it directly; available for conditional class composition | `^2.1.1` |
|
|
154
|
-
| `tailwind-merge` | Used by the `cx()` helper; sharing one version avoids divergent Tailwind merge configs | `^3.6.0` |
|
|
155
|
-
| `tailwind-variants` | Variant/slot config for component class strings — identical strings resolve on both | `^3.2.2` |
|
|
156
|
-
|
|
157
|
-
**Web-only — `optional` peers (a web consumer provides them; RN never does):**
|
|
158
|
-
|
|
159
|
-
| Package | Why peer | Version |
|
|
160
|
-
| ----------------------- | ------------------------------------------------------------------------------------------------------------------ | --------- |
|
|
161
|
-
| `react-dom` | Web React renderer; no RN equivalent | `^19.0.0` |
|
|
162
|
-
| `react-aria-components` | Web-only a11y primitives Untitled UI is built on (quarantined — see cross-platform rule) | `^1.18.0` |
|
|
163
|
-
| `react-router` | Web routing — `providers/RouteProvider` feeds it into RAC's `RouterProvider`; RN uses react-navigation, never this | `^7.0.0` |
|
|
164
|
-
|
|
165
|
-
**App-only (React Native) — `optional` peers (an RN consumer provides them; web never does):**
|
|
166
|
-
|
|
167
|
-
| Package | Why peer | Version |
|
|
168
|
-
| --------------------------------- | ------------------------------------------------------------------------ | ---------- |
|
|
169
|
-
| `react-native` | RN primitives (`View`, `Pressable`, `TextInput`) used by `.native.tsx` | `>=0.79.0` |
|
|
170
|
-
| `nativewind` | Resolves the shared Tailwind class strings to RN styles at build time | `^4.1.0` |
|
|
171
|
-
| `@react-native-aria/interactions` | RN a11y/interaction hooks — the `react-aria-components` equivalent on RN | `>=0.2.7` |
|
|
172
|
-
| `@react-native-aria/focus` | RN focus management hooks (composed by `.native.tsx` overlay components) | `>=0.2.7` |
|
|
65
|
+
The library ships pre-built — compiled ESM and CommonJS with TypeScript declarations — so each subpath resolves to built output in `dist/`.
|
|
173
66
|
|
|
174
|
-
|
|
175
|
-
> as the `x-peer-platforms` field (an `x-`-prefixed field npm/pnpm ignore at install
|
|
176
|
-
> time, since `package.json` allows no comments — purely self-documenting). Nothing
|
|
177
|
-
> enforces consistency, so when you add, rename, or move a peer, update **all three** in
|
|
178
|
-
> lock-step: `peerDependencies`, `peerDependenciesMeta` (the `optional` flag for platform
|
|
179
|
-
> peers), and `x-peer-platforms` — plus the table above.
|
|
67
|
+
## Usage
|
|
180
68
|
|
|
181
|
-
|
|
69
|
+
Components, providers, hooks, and utilities are imported from subpaths that mirror the atomic-design layers:
|
|
182
70
|
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
spurious "missing peer" warning, and **no consumer-side suppression** (`ignoreMissing`,
|
|
188
|
-
`auto-install-peers=false`, `legacy-peer-deps`) is needed. The version ranges still
|
|
189
|
-
apply when a peer **is** present, so a mismatched version is still flagged.
|
|
190
|
-
|
|
191
|
-
**Trade-off (deliberate):** optional peers drop the install-time guarantee that a web
|
|
192
|
-
consumer has `react-aria-components`. That enforcement instead happens where it's
|
|
193
|
-
unambiguous about platform: the **bundler** (a web build importing a RAC-based
|
|
194
|
-
component fails to resolve the missing module) and the **Cursor rules**
|
|
195
|
-
(`cross-platform-components.mdc` quarantines RAC to web `index.tsx`). This keeps the
|
|
196
|
-
single shared package honest for both platforms without forcing either consumer to
|
|
197
|
-
carry the other's dependencies.
|
|
198
|
-
|
|
199
|
-
#### `devDependencies` mirror (local typecheck only — never shipped)
|
|
200
|
-
|
|
201
|
-
Each peer the source actually imports is mirrored in `devDependencies` so the lib's
|
|
202
|
-
own typecheck resolves it:
|
|
203
|
-
|
|
204
|
-
- **Web** (`pnpm typecheck`): `@types/react`, `@types/react-dom`, `react-aria-components`, `react-router`, `clsx`, `tailwind-merge`, `tailwind-variants`.
|
|
205
|
-
- **App** (`pnpm typecheck:native`): `react-native` + `nativewind` (RN module/`className` types). `@react-native-aria/*` are **not** dev-installed yet — they're added per-component when the first overlay `index.native.tsx` (Modal, Select, RadioGroup, …) is written; until then they exist only as optional peers for the RN consumer to provide.
|
|
206
|
-
|
|
207
|
-
`@types/react-native` is intentionally **omitted** — it's deprecated and React Native
|
|
208
|
-
ships its own types since 0.71; adding the DefinitelyTyped package causes duplicate
|
|
209
|
-
global definitions.
|
|
210
|
-
|
|
211
|
-
The class-merge helper is `cx` (`extendTailwindMerge` wrapper, per Untitled UI's Vite
|
|
212
|
-
guide) — not a `cn`/`clsx` wrapper.
|
|
213
|
-
|
|
214
|
-
#### Platform-split typecheck (`tsconfig.json` vs `tsconfig.native.json`)
|
|
215
|
-
|
|
216
|
-
The two platforms have conflicting global types (web has the `DOM` lib; RN does not),
|
|
217
|
-
so they typecheck under separate configs:
|
|
218
|
-
|
|
219
|
-
- `tsconfig.json` → web. Has `lib: ["DOM", …]`; **excludes** `**/*.native.ts(x)` so RN
|
|
220
|
-
files (which import `react-native`) never get checked under the DOM lib.
|
|
221
|
-
- `tsconfig.native.json` → app. Drops the `DOM` lib (`lib: ["ES2020"]`) so any
|
|
222
|
-
accidental `window`/`document`/DOM usage in RN-bound code is a compile error rather
|
|
223
|
-
than a runtime Metro-bundle break. RN module types resolve via normal imports, so no
|
|
224
|
-
`types` override is needed.
|
|
225
|
-
|
|
226
|
-
Because the package currently ships web-only, `tsconfig.native.json` anchors its
|
|
227
|
-
program on the shared, DOM-free utilities (`utilities/cx`, `utilities/isReactComponent`)
|
|
228
|
-
so `typecheck:native` has inputs (no `TS18003`) before any `.native.tsx` exists. New
|
|
229
|
-
`*.native.ts(x)` files are picked up automatically by its include globs.
|
|
230
|
-
|
|
231
|
-
### Tailwind plugins declared by `styles.css` → ui-library `dependencies`
|
|
232
|
-
|
|
233
|
-
| Package | Why |
|
|
234
|
-
| ----------------------------------- | ------------------------------------------------------------------ |
|
|
235
|
-
| `tailwindcss-animate` | `@plugin` declared in `styles.css`; must resolve from this package |
|
|
236
|
-
| `tailwindcss-react-aria-components` | `@plugin` declared in `styles.css`; powers RAC-aware variants |
|
|
237
|
-
|
|
238
|
-
Because `@flipdish/ui-library/styles` declares these via `@plugin`, and
|
|
239
|
-
`@plugin` resolves relative to the file declaring it, the plugins are real
|
|
240
|
-
`dependencies` of ui-library (installed transitively wherever ui-library is) — the
|
|
241
|
-
consumer no longer lists them.
|
|
242
|
-
|
|
243
|
-
### Encapsulated runtime libs → ui-library `dependencies`
|
|
244
|
-
|
|
245
|
-
| Package | Why |
|
|
246
|
-
| ---------------------- | ---------------------------------------------------------------------------------------------- |
|
|
247
|
-
| `react-error-boundary` | Wrapped behind `providers/ErrorBoundary`; consumers use that seam and never import it directly |
|
|
248
|
-
|
|
249
|
-
Unlike the runtime **peers** above (which the consumer also imports), this is an
|
|
250
|
-
implementation detail of `providers/ErrorBoundary`. It's a plain `dependency` so it
|
|
251
|
-
resolves from this package and ships transitively — the consumer imports
|
|
252
|
-
`@flipdish/ui-library/providers/ErrorBoundary`, not `react-error-boundary`.
|
|
253
|
-
It's RN-safe, so it stays a regular dep rather than a web-only one.
|
|
71
|
+
```ts
|
|
72
|
+
// Components — components/<atoms|molecules|organisms|templates>/<Name>
|
|
73
|
+
import { Button } from "@flipdish/ui-library/components/atoms/Button";
|
|
74
|
+
import { NotFoundPage } from "@flipdish/ui-library/components/templates/NotFoundPage";
|
|
254
75
|
|
|
255
|
-
|
|
76
|
+
// Providers — cross-cutting behavioural wrappers
|
|
77
|
+
import { ThemeProvider } from "@flipdish/ui-library/providers/ThemeProvider";
|
|
78
|
+
import { RouteProvider } from "@flipdish/ui-library/providers/RouteProvider";
|
|
79
|
+
import { ErrorBoundary } from "@flipdish/ui-library/providers/ErrorBoundary";
|
|
256
80
|
|
|
257
|
-
|
|
81
|
+
// Hooks
|
|
82
|
+
import { useBreakpoint } from "@flipdish/ui-library/hooks/useBreakpoints";
|
|
83
|
+
import { useClipboard } from "@flipdish/ui-library/hooks/useClipboard";
|
|
258
84
|
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
85
|
+
// Utilities
|
|
86
|
+
import { cx, sortCx } from "@flipdish/ui-library/utilities/cx";
|
|
87
|
+
```
|
|
262
88
|
|
|
263
|
-
|
|
264
|
-
lints TS with Biome, which can't express wildcard atomic-layer import bans):
|
|
89
|
+
### Styling rules
|
|
265
90
|
|
|
266
|
-
-
|
|
267
|
-
- molecules → may import atoms
|
|
268
|
-
- organisms → may import atoms + molecules
|
|
269
|
-
- templates → may import atoms + molecules + organisms
|
|
91
|
+
Use **semantic** token utilities only (`bg-primary`, `text-secondary`, `border-primary`, `bg-brand-solid`, …) — never primitive ramp utilities (`bg-blue-500`) or raw `var(--…)` in `style`. Semantic tokens swap automatically under `[data-theme="dark"]`; primitives don't.
|
|
270
92
|
|
|
271
|
-
|
|
272
|
-
import components).
|
|
93
|
+
## Platform support (web + React Native)
|
|
273
94
|
|
|
274
|
-
|
|
95
|
+
The component API, `tailwind-variants` configs, and `cx`/`sortCx` are shared across platforms; primitives and accessibility libraries diverge via a `.tsx` (web) + `.native.tsx` (RN) file split.
|
|
275
96
|
|
|
276
|
-
Untitled UI
|
|
277
|
-
(the frontend already owns `@/`). When pasting a component, rewrite its imports to
|
|
278
|
-
package paths and drop the file into the right atomic layer:
|
|
97
|
+
`react-aria-components` (which Untitled UI is built on) is **web-only**, so a component is React Native-ready only once it ships an `index.native.tsx` sibling. The presence of that file is the source of truth — Metro resolves `index.native.tsx` automatically, while web bundlers use the `index.tsx`.
|
|
279
98
|
|
|
280
|
-
|
|
281
|
-
| ---------------------------------- | --------------------------------------------------------------- |
|
|
282
|
-
| `@/utils/cx` | `@flipdish/ui-library/utilities/cx` |
|
|
283
|
-
| `@/components/base/buttons/button` | `@flipdish/ui-library/components/atoms/Button` (classify layer) |
|
|
284
|
-
| `@/hooks/use-x` | `@flipdish/ui-library/hooks/useX` |
|
|
285
|
-
| `@untitledui/icons` | `@flipdish/ui-icons` (same named exports) |
|
|
99
|
+
**Today the library is web-only** — no component ships a `.native.tsx` sibling yet. As React Native support lands per component, check the component's folder for an `index.native.tsx` ([browse the source](https://github.com/flipdishbytes/flipdish-design-system/tree/main/packages/ui-library/src/components)) rather than relying on a list here that would drift between releases.
|
|
286
100
|
|
|
287
|
-
|
|
288
|
-
NOT a dependency. Icons live in the separate `@flipdish/ui-icons` package,
|
|
289
|
-
which re-exports `@untitledui/icons` behind a stable seam. When pasting a component
|
|
290
|
-
that imports `@untitledui/icons`, rewrite the import to `@flipdish/ui-icons`
|
|
291
|
-
(the named exports are identical) — never import `@untitledui/icons` directly here.
|
|
101
|
+
## Changelog
|
|
292
102
|
|
|
293
|
-
|
|
294
|
-
ramp utilities (`bg-blue-500`). This package's `styles.css`
|
|
295
|
-
(`@flipdish/ui-library/styles`) provides the Tailwind plugins, `dark`
|
|
296
|
-
variant (mapped to `[data-theme="dark"]`), and `@utility` definitions
|
|
297
|
-
(`transition-inherit-all`, `scrollbar-hide`) these components expect — the consumer
|
|
298
|
-
just imports it. See `.cursor/rules/atomic-design.mdc`.
|
|
103
|
+
See [CHANGELOG.md](https://github.com/flipdishbytes/flipdish-design-system/blob/main/packages/ui-library/CHANGELOG.md) for release history.
|
|
299
104
|
|
|
300
|
-
##
|
|
105
|
+
## Contributing
|
|
301
106
|
|
|
302
|
-
This
|
|
303
|
-
API, `tailwind-variants` configs, and `cx`/`sortCx` are shared; primitives and a11y
|
|
304
|
-
libraries diverge via a `.tsx` (web) + `.native.tsx` (RN) file split. See
|
|
305
|
-
`.cursor/rules/cross-platform-components.mdc`.
|
|
306
|
-
|
|
307
|
-
`react-aria-components` (which Untitled UI is built on) is **web-only**. A pasted
|
|
308
|
-
component is web-only until an `index.native.tsx` sibling is written. Metro falls
|
|
309
|
-
back to `index.tsx` when no native sibling exists, so RN consumers must only import
|
|
310
|
-
components marked RN-ready below.
|
|
311
|
-
|
|
312
|
-
| Component | Layer | RN status |
|
|
313
|
-
| ---------------- | -------- | ------------------------------------------------------- |
|
|
314
|
-
| Avatar | atom | TODO(RN) (web markup; no `.native.tsx` yet) |
|
|
315
|
-
| Badge | atom | TODO(RN) (web markup; no `.native.tsx` yet) |
|
|
316
|
-
| Button | atom | TODO(RN) (RAC-based; web-only until `.native.tsx`) |
|
|
317
|
-
| Checkbox | atom | TODO(RN) (RAC-based; web-only until `.native.tsx`) |
|
|
318
|
-
| Divider | atom | TODO(RN) (web markup; no `.native.tsx` yet) |
|
|
319
|
-
| Dot | atom | TODO(RN) (web markup; no `.native.tsx` yet) |
|
|
320
|
-
| FeaturedIcon | atom | TODO(RN) (web markup; no `.native.tsx` yet) |
|
|
321
|
-
| Input | atom | TODO(RN) (RAC-based; web-only until `.native.tsx`) |
|
|
322
|
-
| LoadingIndicator | atom | TODO(RN) (web markup; no `.native.tsx` yet) |
|
|
323
|
-
| RadioButton | atom | TODO(RN) (RAC-based; web-only until `.native.tsx`) |
|
|
324
|
-
| Toggle | atom | TODO(RN) (RAC-based; web-only until `.native.tsx`) |
|
|
325
|
-
| Tooltip | atom | TODO(RN) (RAC-based; web-only until `.native.tsx`) |
|
|
326
|
-
| Breadcrumbs | molecule | TODO(RN) (RAC-based; web-only until `.native.tsx`) |
|
|
327
|
-
| ButtonGroup | molecule | TODO(RN) (RAC-based; web-only until `.native.tsx`) |
|
|
328
|
-
| Dropdown | molecule | TODO(RN) (RAC-based; web-only until `.native.tsx`) |
|
|
329
|
-
| RadioGroup | molecule | TODO(RN) (RAC-based; web-only until `.native.tsx`) |
|
|
330
|
-
| SectionHeader | molecule | TODO(RN) (web markup; no `.native.tsx` yet) |
|
|
331
|
-
| Select | molecule | TODO(RN) (RAC-based; web-only until `.native.tsx`) |
|
|
332
|
-
| PageHeader | organism | TODO(RN) (web markup; composes Button + Input) |
|
|
333
|
-
| NotFoundPage | template | No (web-only template) |
|
|
334
|
-
| PageLayout | template | No (web-only template; renders `<main>`) |
|
|
335
|
-
| ErrorBoundary | provider | TODO(RN) (logic RN-safe; default fallback is a `<div>`) |
|
|
336
|
-
|
|
337
|
-
_(Table grows as components are added. `Yes` = has `.native.tsx`; `No` = web-only by
|
|
338
|
-
design; `TODO(RN)` = web ships, RN sibling pending.)_
|
|
107
|
+
This package lives in the [`flipdish-design-system`](https://github.com/flipdishbytes/flipdish-design-system) monorepo. Contributor documentation — folder conventions, how Untitled UI components are adapted, the web/native file split, and dependency rules — lives alongside the source there.
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var React = require('react');
|
|
4
|
+
|
|
5
|
+
const screens = {
|
|
6
|
+
sm: '640px',
|
|
7
|
+
md: '768px',
|
|
8
|
+
lg: '1024px',
|
|
9
|
+
xl: '1280px',
|
|
10
|
+
'2xl': '1536px',
|
|
11
|
+
};
|
|
12
|
+
/**
|
|
13
|
+
* Checks whether a particular Tailwind CSS viewport size applies.
|
|
14
|
+
*
|
|
15
|
+
* @param size The size to check, which must either be included in Tailwind CSS's
|
|
16
|
+
* list of default screen sizes, or added to the Tailwind CSS config file.
|
|
17
|
+
*
|
|
18
|
+
* @returns A boolean indicating whether the viewport size applies.
|
|
19
|
+
*/
|
|
20
|
+
const useBreakpoint = (size) => {
|
|
21
|
+
const query = `(min-width: ${screens[size]})`;
|
|
22
|
+
const getMatches = () => (typeof window !== 'undefined' && typeof window.matchMedia === 'function' ? window.matchMedia(query).matches : false);
|
|
23
|
+
const [matches, setMatches] = React.useState(getMatches);
|
|
24
|
+
React.useEffect(() => {
|
|
25
|
+
if (typeof window === 'undefined' || typeof window.matchMedia !== 'function') {
|
|
26
|
+
setMatches(false);
|
|
27
|
+
return;
|
|
28
|
+
}
|
|
29
|
+
const breakpoint = window.matchMedia(query);
|
|
30
|
+
setMatches(breakpoint.matches);
|
|
31
|
+
const handleChange = (value) => setMatches(value.matches);
|
|
32
|
+
breakpoint.addEventListener('change', handleChange);
|
|
33
|
+
return () => breakpoint.removeEventListener('change', handleChange);
|
|
34
|
+
}, [query]);
|
|
35
|
+
return matches;
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
exports.useBreakpoint = useBreakpoint;
|
|
39
|
+
//# sourceMappingURL=index.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.cjs","sources":["../../../src/hooks/useBreakpoints/index.ts"],"sourcesContent":[null],"names":["useState","useEffect"],"mappings":";;;;AAEA,MAAM,OAAO,GAAG;AACd,IAAA,EAAE,EAAE,OAAO;AACX,IAAA,EAAE,EAAE,OAAO;AACX,IAAA,EAAE,EAAE,QAAQ;AACZ,IAAA,EAAE,EAAE,QAAQ;AACZ,IAAA,KAAK,EAAE,QAAQ;CACP;AAIV;;;;;;;AAOG;AACI,MAAM,aAAa,GAAG,CAAC,IAAgB,KAAI;IAChD,MAAM,KAAK,GAAG,CAAA,YAAA,EAAe,OAAO,CAAC,IAAI,CAAC,GAAG;AAE7C,IAAA,MAAM,UAAU,GAAG,OAAO,OAAO,MAAM,KAAK,WAAW,IAAI,OAAO,MAAM,CAAC,UAAU,KAAK,UAAU,GAAG,MAAM,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC,OAAO,GAAG,KAAK,CAAC;IAE9I,MAAM,CAAC,OAAO,EAAE,UAAU,CAAC,GAAGA,cAAQ,CAAC,UAAU,CAAC;IAElDC,eAAS,CAAC,MAAK;AACb,QAAA,IAAI,OAAO,MAAM,KAAK,WAAW,IAAI,OAAO,MAAM,CAAC,UAAU,KAAK,UAAU,EAAE;YAC5E,UAAU,CAAC,KAAK,CAAC;YACjB;QACF;QAEA,MAAM,UAAU,GAAG,MAAM,CAAC,UAAU,CAAC,KAAK,CAAC;AAE3C,QAAA,UAAU,CAAC,UAAU,CAAC,OAAO,CAAC;AAE9B,QAAA,MAAM,YAAY,GAAG,CAAC,KAA0B,KAAK,UAAU,CAAC,KAAK,CAAC,OAAO,CAAC;AAE9E,QAAA,UAAU,CAAC,gBAAgB,CAAC,QAAQ,EAAE,YAAY,CAAC;QACnD,OAAO,MAAM,UAAU,CAAC,mBAAmB,CAAC,QAAQ,EAAE,YAAY,CAAC;AACrE,IAAA,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC;AAEX,IAAA,OAAO,OAAO;AAChB;;;;"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
declare const screens: {
|
|
2
|
+
readonly sm: "640px";
|
|
3
|
+
readonly md: "768px";
|
|
4
|
+
readonly lg: "1024px";
|
|
5
|
+
readonly xl: "1280px";
|
|
6
|
+
readonly '2xl': "1536px";
|
|
7
|
+
};
|
|
8
|
+
type Breakpoint = keyof typeof screens;
|
|
9
|
+
/**
|
|
10
|
+
* Checks whether a particular Tailwind CSS viewport size applies.
|
|
11
|
+
*
|
|
12
|
+
* @param size The size to check, which must either be included in Tailwind CSS's
|
|
13
|
+
* list of default screen sizes, or added to the Tailwind CSS config file.
|
|
14
|
+
*
|
|
15
|
+
* @returns A boolean indicating whether the viewport size applies.
|
|
16
|
+
*/
|
|
17
|
+
export declare const useBreakpoint: (size: Breakpoint) => boolean;
|
|
18
|
+
export {};
|
|
19
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/hooks/useBreakpoints/index.ts"],"names":[],"mappings":"AAEA,QAAA,MAAM,OAAO;;;;;;CAMH,CAAC;AAEX,KAAK,UAAU,GAAG,MAAM,OAAO,OAAO,CAAC;AAEvC;;;;;;;GAOG;AACH,eAAO,MAAM,aAAa,GAAI,MAAM,UAAU,YAwB7C,CAAC"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { useState, useEffect } from 'react';
|
|
2
|
+
|
|
3
|
+
const screens = {
|
|
4
|
+
sm: '640px',
|
|
5
|
+
md: '768px',
|
|
6
|
+
lg: '1024px',
|
|
7
|
+
xl: '1280px',
|
|
8
|
+
'2xl': '1536px',
|
|
9
|
+
};
|
|
10
|
+
/**
|
|
11
|
+
* Checks whether a particular Tailwind CSS viewport size applies.
|
|
12
|
+
*
|
|
13
|
+
* @param size The size to check, which must either be included in Tailwind CSS's
|
|
14
|
+
* list of default screen sizes, or added to the Tailwind CSS config file.
|
|
15
|
+
*
|
|
16
|
+
* @returns A boolean indicating whether the viewport size applies.
|
|
17
|
+
*/
|
|
18
|
+
const useBreakpoint = (size) => {
|
|
19
|
+
const query = `(min-width: ${screens[size]})`;
|
|
20
|
+
const getMatches = () => (typeof window !== 'undefined' && typeof window.matchMedia === 'function' ? window.matchMedia(query).matches : false);
|
|
21
|
+
const [matches, setMatches] = useState(getMatches);
|
|
22
|
+
useEffect(() => {
|
|
23
|
+
if (typeof window === 'undefined' || typeof window.matchMedia !== 'function') {
|
|
24
|
+
setMatches(false);
|
|
25
|
+
return;
|
|
26
|
+
}
|
|
27
|
+
const breakpoint = window.matchMedia(query);
|
|
28
|
+
setMatches(breakpoint.matches);
|
|
29
|
+
const handleChange = (value) => setMatches(value.matches);
|
|
30
|
+
breakpoint.addEventListener('change', handleChange);
|
|
31
|
+
return () => breakpoint.removeEventListener('change', handleChange);
|
|
32
|
+
}, [query]);
|
|
33
|
+
return matches;
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
export { useBreakpoint };
|
|
37
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sources":["../../../src/hooks/useBreakpoints/index.ts"],"sourcesContent":[null],"names":[],"mappings":";;AAEA,MAAM,OAAO,GAAG;AACd,IAAA,EAAE,EAAE,OAAO;AACX,IAAA,EAAE,EAAE,OAAO;AACX,IAAA,EAAE,EAAE,QAAQ;AACZ,IAAA,EAAE,EAAE,QAAQ;AACZ,IAAA,KAAK,EAAE,QAAQ;CACP;AAIV;;;;;;;AAOG;AACI,MAAM,aAAa,GAAG,CAAC,IAAgB,KAAI;IAChD,MAAM,KAAK,GAAG,CAAA,YAAA,EAAe,OAAO,CAAC,IAAI,CAAC,GAAG;AAE7C,IAAA,MAAM,UAAU,GAAG,OAAO,OAAO,MAAM,KAAK,WAAW,IAAI,OAAO,MAAM,CAAC,UAAU,KAAK,UAAU,GAAG,MAAM,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC,OAAO,GAAG,KAAK,CAAC;IAE9I,MAAM,CAAC,OAAO,EAAE,UAAU,CAAC,GAAG,QAAQ,CAAC,UAAU,CAAC;IAElD,SAAS,CAAC,MAAK;AACb,QAAA,IAAI,OAAO,MAAM,KAAK,WAAW,IAAI,OAAO,MAAM,CAAC,UAAU,KAAK,UAAU,EAAE;YAC5E,UAAU,CAAC,KAAK,CAAC;YACjB;QACF;QAEA,MAAM,UAAU,GAAG,MAAM,CAAC,UAAU,CAAC,KAAK,CAAC;AAE3C,QAAA,UAAU,CAAC,UAAU,CAAC,OAAO,CAAC;AAE9B,QAAA,MAAM,YAAY,GAAG,CAAC,KAA0B,KAAK,UAAU,CAAC,KAAK,CAAC,OAAO,CAAC;AAE9E,QAAA,UAAU,CAAC,gBAAgB,CAAC,QAAQ,EAAE,YAAY,CAAC;QACnD,OAAO,MAAM,UAAU,CAAC,mBAAmB,CAAC,QAAQ,EAAE,YAAY,CAAC;AACrE,IAAA,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC;AAEX,IAAA,OAAO,OAAO;AAChB;;;;"}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var React = require('react');
|
|
4
|
+
|
|
5
|
+
const DEFAULT_TIMEOUT = 2000;
|
|
6
|
+
/**
|
|
7
|
+
* Custom hook to copy text to the clipboard.
|
|
8
|
+
*
|
|
9
|
+
* @returns {UseClipboardReturnType} - An object containing the copied state and the copy function.
|
|
10
|
+
*/
|
|
11
|
+
const useClipboard = () => {
|
|
12
|
+
const [copied, setCopied] = React.useState(false);
|
|
13
|
+
const resetTimerRef = React.useRef(null);
|
|
14
|
+
const scheduleReset = () => {
|
|
15
|
+
if (resetTimerRef.current)
|
|
16
|
+
clearTimeout(resetTimerRef.current);
|
|
17
|
+
resetTimerRef.current = setTimeout(() => setCopied(false), DEFAULT_TIMEOUT);
|
|
18
|
+
};
|
|
19
|
+
React.useEffect(() => {
|
|
20
|
+
return () => {
|
|
21
|
+
if (resetTimerRef.current)
|
|
22
|
+
clearTimeout(resetTimerRef.current);
|
|
23
|
+
};
|
|
24
|
+
}, []);
|
|
25
|
+
// Fallback function for older browsers
|
|
26
|
+
const fallback = (text, id) => {
|
|
27
|
+
try {
|
|
28
|
+
// Textarea to copy the text to the clipboard
|
|
29
|
+
const textArea = document.createElement('textarea');
|
|
30
|
+
textArea.value = text;
|
|
31
|
+
textArea.style.position = 'absolute';
|
|
32
|
+
textArea.style.left = '-99999px';
|
|
33
|
+
document.body.appendChild(textArea);
|
|
34
|
+
textArea.select();
|
|
35
|
+
const success = document.execCommand('copy');
|
|
36
|
+
textArea.remove();
|
|
37
|
+
if (success) {
|
|
38
|
+
setCopied(id || true);
|
|
39
|
+
scheduleReset();
|
|
40
|
+
}
|
|
41
|
+
return success ? { success: true } : { success: false, error: new Error('execCommand returned false') };
|
|
42
|
+
}
|
|
43
|
+
catch (err) {
|
|
44
|
+
return {
|
|
45
|
+
success: false,
|
|
46
|
+
error: err instanceof Error ? err : new Error('Fallback copy failed'),
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
};
|
|
50
|
+
// biome-ignore lint/correctness/useExhaustiveDependencies: We need to return the copied state and the copy function
|
|
51
|
+
const copy = React.useCallback(async (text, id) => {
|
|
52
|
+
if (navigator.clipboard && window.isSecureContext) {
|
|
53
|
+
try {
|
|
54
|
+
await navigator.clipboard.writeText(text);
|
|
55
|
+
setCopied(id || true);
|
|
56
|
+
scheduleReset();
|
|
57
|
+
return { success: true };
|
|
58
|
+
}
|
|
59
|
+
catch (_err) {
|
|
60
|
+
// If modern method fails, try fallback
|
|
61
|
+
return fallback(text, id);
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
return fallback(text, id);
|
|
65
|
+
}, []);
|
|
66
|
+
return { copied, copy };
|
|
67
|
+
};
|
|
68
|
+
|
|
69
|
+
exports.useClipboard = useClipboard;
|
|
70
|
+
//# sourceMappingURL=index.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.cjs","sources":["../../../src/hooks/useClipboard/index.ts"],"sourcesContent":[null],"names":["useState","useRef","useEffect","useCallback"],"mappings":";;;;AAEA,MAAM,eAAe,GAAG,IAAI;AAqB5B;;;;AAIG;AACI,MAAM,YAAY,GAAG,MAA6B;IACvD,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,GAAGA,cAAQ,CAAmB,KAAK,CAAC;AAC7D,IAAA,MAAM,aAAa,GAAGC,YAAM,CAAuC,IAAI,CAAC;IAExE,MAAM,aAAa,GAAG,MAAK;QACzB,IAAI,aAAa,CAAC,OAAO;AAAE,YAAA,YAAY,CAAC,aAAa,CAAC,OAAO,CAAC;AAC9D,QAAA,aAAa,CAAC,OAAO,GAAG,UAAU,CAAC,MAAM,SAAS,CAAC,KAAK,CAAC,EAAE,eAAe,CAAC;AAC7E,IAAA,CAAC;IAEDC,eAAS,CAAC,MAAK;AACb,QAAA,OAAO,MAAK;YACV,IAAI,aAAa,CAAC,OAAO;AAAE,gBAAA,YAAY,CAAC,aAAa,CAAC,OAAO,CAAC;AAChE,QAAA,CAAC;IACH,CAAC,EAAE,EAAE,CAAC;;AAGN,IAAA,MAAM,QAAQ,GAAG,CAAC,IAAY,EAAE,EAAW,KAAI;AAC7C,QAAA,IAAI;;YAEF,MAAM,QAAQ,GAAG,QAAQ,CAAC,aAAa,CAAC,UAAU,CAAC;AACnD,YAAA,QAAQ,CAAC,KAAK,GAAG,IAAI;AACrB,YAAA,QAAQ,CAAC,KAAK,CAAC,QAAQ,GAAG,UAAU;AACpC,YAAA,QAAQ,CAAC,KAAK,CAAC,IAAI,GAAG,UAAU;AAEhC,YAAA,QAAQ,CAAC,IAAI,CAAC,WAAW,CAAC,QAAQ,CAAC;YACnC,QAAQ,CAAC,MAAM,EAAE;YAEjB,MAAM,OAAO,GAAG,QAAQ,CAAC,WAAW,CAAC,MAAM,CAAC;YAC5C,QAAQ,CAAC,MAAM,EAAE;YAEjB,IAAI,OAAO,EAAE;AACX,gBAAA,SAAS,CAAC,EAAE,IAAI,IAAI,CAAC;AACrB,gBAAA,aAAa,EAAE;YACjB;YAEA,OAAO,OAAO,GAAG,EAAE,OAAO,EAAE,IAAI,EAAE,GAAG,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,IAAI,KAAK,CAAC,4BAA4B,CAAC,EAAE;QACzG;QAAE,OAAO,GAAG,EAAE;YACZ,OAAO;AACL,gBAAA,OAAO,EAAE,KAAK;AACd,gBAAA,KAAK,EAAE,GAAG,YAAY,KAAK,GAAG,GAAG,GAAG,IAAI,KAAK,CAAC,sBAAsB,CAAC;aACtE;QACH;AACF,IAAA,CAAC;;IAGD,MAAM,IAAI,GAAGC,iBAAW,CAAC,OAAO,IAAY,EAAE,EAAW,KAAI;QAC3D,IAAI,SAAS,CAAC,SAAS,IAAI,MAAM,CAAC,eAAe,EAAE;AACjD,YAAA,IAAI;gBACF,MAAM,SAAS,CAAC,SAAS,CAAC,SAAS,CAAC,IAAI,CAAC;AAEzC,gBAAA,SAAS,CAAC,EAAE,IAAI,IAAI,CAAC;AACrB,gBAAA,aAAa,EAAE;AAEf,gBAAA,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE;YAC1B;YAAE,OAAO,IAAI,EAAE;;AAEb,gBAAA,OAAO,QAAQ,CAAC,IAAI,EAAE,EAAE,CAAC;YAC3B;QACF;AACA,QAAA,OAAO,QAAQ,CAAC,IAAI,EAAE,EAAE,CAAC;IAC3B,CAAC,EAAE,EAAE,CAAC;AAEN,IAAA,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE;AACzB;;;;"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
type UseClipboardReturnType = {
|
|
2
|
+
/**
|
|
3
|
+
* The state indicating whether the text has been copied.
|
|
4
|
+
* If a string is provided, it will be used as the identifier for the copied state.
|
|
5
|
+
*/
|
|
6
|
+
copied: string | boolean;
|
|
7
|
+
/**
|
|
8
|
+
* Function to copy text to the clipboard using the modern clipboard API.
|
|
9
|
+
* Falls back to the fallback function if the modern API fails.
|
|
10
|
+
*
|
|
11
|
+
* @param {string} text - The text to be copied.
|
|
12
|
+
* @param {string} [id] - Optional identifier to set the copied state.
|
|
13
|
+
* @returns {Promise<Object>} - A promise that resolves to an object containing:
|
|
14
|
+
* - `success` (boolean): Whether the copy operation was successful.
|
|
15
|
+
* - `error` (Error | undefined): The error object if the copy operation failed.
|
|
16
|
+
*/
|
|
17
|
+
copy: (text: string, id?: string) => Promise<{
|
|
18
|
+
success: boolean;
|
|
19
|
+
error?: Error;
|
|
20
|
+
}>;
|
|
21
|
+
};
|
|
22
|
+
/**
|
|
23
|
+
* Custom hook to copy text to the clipboard.
|
|
24
|
+
*
|
|
25
|
+
* @returns {UseClipboardReturnType} - An object containing the copied state and the copy function.
|
|
26
|
+
*/
|
|
27
|
+
export declare const useClipboard: () => UseClipboardReturnType;
|
|
28
|
+
export {};
|
|
29
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/hooks/useClipboard/index.ts"],"names":[],"mappings":"AAIA,KAAK,sBAAsB,GAAG;IAC5B;;;OAGG;IACH,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC;IACzB;;;;;;;;;OASG;IACH,IAAI,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,CAAC,EAAE,MAAM,KAAK,OAAO,CAAC;QAAE,OAAO,EAAE,OAAO,CAAC;QAAC,KAAK,CAAC,EAAE,KAAK,CAAA;KAAE,CAAC,CAAC;CACnF,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,YAAY,QAAO,sBA+D/B,CAAC"}
|