@duro-app/ui 0.34.6 → 0.34.8

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 (40) hide show
  1. package/dist/components/Badge/Badge.d.ts.map +1 -1
  2. package/dist/components/Badge/styles.css.d.ts +3 -0
  3. package/dist/components/Badge/styles.css.d.ts.map +1 -1
  4. package/dist/components/Button/Button.d.ts.map +1 -1
  5. package/dist/components/Button/styles.css.d.ts +3 -0
  6. package/dist/components/Button/styles.css.d.ts.map +1 -1
  7. package/dist/components/Checkbox/Checkbox.d.ts.map +1 -1
  8. package/dist/components/Checkbox/styles.css.d.ts +3 -0
  9. package/dist/components/Checkbox/styles.css.d.ts.map +1 -1
  10. package/dist/components/InputGroup/InputGroup.d.ts.map +1 -1
  11. package/dist/components/InputGroup/styles.css.d.ts +3 -0
  12. package/dist/components/InputGroup/styles.css.d.ts.map +1 -1
  13. package/dist/components/Switch/Switch.d.ts.map +1 -1
  14. package/dist/components/Switch/styles.css.d.ts +3 -0
  15. package/dist/components/Switch/styles.css.d.ts.map +1 -1
  16. package/dist/components/ThemeProvider/ThemeProvider.native.d.ts +10 -0
  17. package/dist/components/ThemeProvider/ThemeProvider.native.d.ts.map +1 -0
  18. package/dist/index.js +866 -858
  19. package/dist/index.js.map +1 -1
  20. package/dist/index.native.d.ts +1 -0
  21. package/dist/index.native.d.ts.map +1 -1
  22. package/dist/platform.d.ts +12 -0
  23. package/dist/platform.d.ts.map +1 -0
  24. package/dist/platform.native.d.ts +2 -0
  25. package/dist/platform.native.d.ts.map +1 -0
  26. package/package.json +2 -2
  27. package/src/components/Badge/Badge.tsx +6 -1
  28. package/src/components/Badge/styles.css.ts +5 -0
  29. package/src/components/Button/Button.tsx +2 -0
  30. package/src/components/Button/styles.css.ts +5 -0
  31. package/src/components/Checkbox/Checkbox.tsx +9 -2
  32. package/src/components/Checkbox/styles.css.ts +5 -0
  33. package/src/components/InputGroup/InputGroup.tsx +2 -0
  34. package/src/components/InputGroup/styles.css.ts +5 -0
  35. package/src/components/Switch/Switch.tsx +4 -1
  36. package/src/components/Switch/styles.css.ts +5 -0
  37. package/src/components/ThemeProvider/ThemeProvider.native.tsx +49 -0
  38. package/src/index.native.ts +8 -0
  39. package/src/platform.native.ts +3 -0
  40. package/src/platform.ts +11 -0
@@ -28,4 +28,5 @@ export { Stack, type SpacingKey } from './components/Stack/Stack';
28
28
  export { Inline } from './components/Inline/Inline';
29
29
  export { Cluster } from './components/Cluster/Cluster';
30
30
  export { Grid } from './components/Grid/Grid';
31
+ export { ThemeProvider, usePortalMount, type ThemeName, } from './components/ThemeProvider/ThemeProvider';
31
32
  //# sourceMappingURL=index.native.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.native.d.ts","sourceRoot":"","sources":["../src/index.native.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAGH,OAAO,EAAC,KAAK,EAAE,KAAK,YAAY,EAAE,KAAK,SAAS,EAAC,MAAM,0BAA0B,CAAA;AACjF,OAAO,EAAC,MAAM,EAAE,KAAK,aAAa,EAAE,KAAK,UAAU,EAAC,MAAM,4BAA4B,CAAA;AACtF,OAAO,EAAC,IAAI,EAAE,KAAK,WAAW,EAAE,KAAK,QAAQ,EAAC,MAAM,wBAAwB,CAAA;AAC5E,OAAO,EAAC,QAAQ,EAAC,MAAM,gCAAgC,CAAA;AACvD,OAAO,EAAC,OAAO,EAAE,KAAK,cAAc,EAAC,MAAM,8BAA8B,CAAA;AACzE,OAAO,EAAC,KAAK,EAAE,KAAK,YAAY,EAAC,MAAM,0BAA0B,CAAA;AACjE,OAAO,EAAC,MAAM,EAAC,MAAM,4BAA4B,CAAA;AACjD,OAAO,EAAC,IAAI,EAAE,KAAK,WAAW,EAAE,KAAK,SAAS,EAAC,MAAM,wBAAwB,CAAA;AAC7E,OAAO,EAAC,QAAQ,EAAE,KAAK,eAAe,EAAC,MAAM,gCAAgC,CAAA;AAG7E,OAAO,EAAC,KAAK,EAAC,MAAM,0BAA0B,CAAA;AAC9C,OAAO,EAAC,UAAU,EAAC,MAAM,oCAAoC,CAAA;AAG7D,OAAO,EAAC,KAAK,EAAE,KAAK,UAAU,EAAC,MAAM,0BAA0B,CAAA;AAC/D,OAAO,EAAC,MAAM,EAAC,MAAM,4BAA4B,CAAA;AACjD,OAAO,EAAC,OAAO,EAAC,MAAM,8BAA8B,CAAA;AACpD,OAAO,EAAC,IAAI,EAAC,MAAM,wBAAwB,CAAA"}
1
+ {"version":3,"file":"index.native.d.ts","sourceRoot":"","sources":["../src/index.native.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAGH,OAAO,EAAC,KAAK,EAAE,KAAK,YAAY,EAAE,KAAK,SAAS,EAAC,MAAM,0BAA0B,CAAA;AACjF,OAAO,EAAC,MAAM,EAAE,KAAK,aAAa,EAAE,KAAK,UAAU,EAAC,MAAM,4BAA4B,CAAA;AACtF,OAAO,EAAC,IAAI,EAAE,KAAK,WAAW,EAAE,KAAK,QAAQ,EAAC,MAAM,wBAAwB,CAAA;AAC5E,OAAO,EAAC,QAAQ,EAAC,MAAM,gCAAgC,CAAA;AACvD,OAAO,EAAC,OAAO,EAAE,KAAK,cAAc,EAAC,MAAM,8BAA8B,CAAA;AACzE,OAAO,EAAC,KAAK,EAAE,KAAK,YAAY,EAAC,MAAM,0BAA0B,CAAA;AACjE,OAAO,EAAC,MAAM,EAAC,MAAM,4BAA4B,CAAA;AACjD,OAAO,EAAC,IAAI,EAAE,KAAK,WAAW,EAAE,KAAK,SAAS,EAAC,MAAM,wBAAwB,CAAA;AAC7E,OAAO,EAAC,QAAQ,EAAE,KAAK,eAAe,EAAC,MAAM,gCAAgC,CAAA;AAG7E,OAAO,EAAC,KAAK,EAAC,MAAM,0BAA0B,CAAA;AAC9C,OAAO,EAAC,UAAU,EAAC,MAAM,oCAAoC,CAAA;AAG7D,OAAO,EAAC,KAAK,EAAE,KAAK,UAAU,EAAC,MAAM,0BAA0B,CAAA;AAC/D,OAAO,EAAC,MAAM,EAAC,MAAM,4BAA4B,CAAA;AACjD,OAAO,EAAC,OAAO,EAAC,MAAM,8BAA8B,CAAA;AACpD,OAAO,EAAC,IAAI,EAAC,MAAM,wBAAwB,CAAA;AAI3C,OAAO,EACL,aAAa,EACb,cAAc,EACd,KAAK,SAAS,GACf,MAAM,0CAA0C,CAAA"}
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Platform flag resolved by the bundler's platform extensions: web bundlers
3
+ * (Vite/Rollup) read THIS file (`isNative = false`); Metro reads
4
+ * `platform.native.ts` (`isNative = true`) on React Native / Expo.
5
+ *
6
+ * It lets shared components layer a native-only style override without
7
+ * importing `react-native` on web (the DS web build has no react-native).
8
+ * Typed `boolean` (not the `false` literal) so `isNative && styles.x` stays a
9
+ * `false | Style` union in style arrays rather than narrowing to `false`.
10
+ */
11
+ export declare const isNative: boolean;
12
+ //# sourceMappingURL=platform.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"platform.d.ts","sourceRoot":"","sources":["../src/platform.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AACH,eAAO,MAAM,QAAQ,EAAE,OAAe,CAAA"}
@@ -0,0 +1,2 @@
1
+ export declare const isNative: boolean;
2
+ //# sourceMappingURL=platform.native.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"platform.native.d.ts","sourceRoot":"","sources":["../src/platform.native.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,QAAQ,EAAE,OAAc,CAAA"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@duro-app/ui",
3
- "version": "0.34.6",
3
+ "version": "0.34.8",
4
4
  "type": "module",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -54,7 +54,7 @@
54
54
  }
55
55
  },
56
56
  "dependencies": {
57
- "@duro-app/tokens": "^0.34.6"
57
+ "@duro-app/tokens": "^0.34.8"
58
58
  },
59
59
  "devDependencies": {
60
60
  "@babel/preset-typescript": "^7.28.0",
@@ -1,5 +1,6 @@
1
1
  import type {ReactNode} from 'react'
2
2
  import {html} from 'react-strict-dom'
3
+ import {isNative} from '../../platform'
3
4
  import {styles} from './styles.css'
4
5
 
5
6
  export type BadgeVariant = 'default' | 'success' | 'warning' | 'error' | 'info'
@@ -17,5 +18,9 @@ const sizeMap = {
17
18
  } as const
18
19
 
19
20
  export function Badge({variant = 'default', size = 'md', children}: BadgeProps) {
20
- return <html.span style={[styles.base, sizeMap[size], styles[variant]]}>{children}</html.span>
21
+ return (
22
+ <html.span style={[styles.base, isNative && styles.nativeFlex, sizeMap[size], styles[variant]]}>
23
+ {children}
24
+ </html.span>
25
+ )
21
26
  }
@@ -48,4 +48,9 @@ export const styles = css.create({
48
48
  backgroundColor: colors.infoBg,
49
49
  color: colors.infoText,
50
50
  },
51
+ // RSD-native only honors display:'flex' (not 'inline-flex'). Layered on
52
+ // native via `isNative` so the flex container applies; web keeps inline-flex.
53
+ nativeFlex: {
54
+ display: 'flex',
55
+ },
51
56
  })
@@ -1,5 +1,6 @@
1
1
  import type {ReactNode} from 'react'
2
2
  import {html} from 'react-strict-dom'
3
+ import {isNative} from '../../platform'
3
4
  import {styles} from './styles.css'
4
5
 
5
6
  export type ButtonVariant = 'primary' | 'secondary' | 'inverseSecondary' | 'link' | 'danger'
@@ -36,6 +37,7 @@ export function Button({
36
37
  onClick={onClick}
37
38
  style={[
38
39
  styles.base,
40
+ isNative && styles.nativeFlex,
39
41
  sizeMap[size],
40
42
  styles[variant],
41
43
  fullWidth && styles.fullWidth,
@@ -116,4 +116,9 @@ export const styles = css.create({
116
116
  opacity: 0.5,
117
117
  cursor: 'not-allowed',
118
118
  },
119
+ // RSD-native only honors display:'flex' (not 'inline-flex'). Layered on
120
+ // native via `isNative` so the flex container applies; web keeps inline-flex.
121
+ nativeFlex: {
122
+ display: 'flex',
123
+ },
119
124
  })
@@ -1,5 +1,6 @@
1
1
  import {type ReactNode, useState, useCallback} from 'react'
2
2
  import {html} from 'react-strict-dom'
3
+ import {isNative} from '../../platform'
3
4
  import {styles} from './styles.css'
4
5
 
5
6
  interface CheckboxProps {
@@ -39,7 +40,9 @@ export function Checkbox({
39
40
  )
40
41
 
41
42
  return (
42
- <html.label style={[styles.root, disabled && styles.rootDisabled]}>
43
+ <html.label
44
+ style={[styles.root, isNative && styles.nativeFlex, disabled && styles.rootDisabled]}
45
+ >
43
46
  <html.input
44
47
  type="checkbox"
45
48
  name={name}
@@ -52,7 +55,11 @@ export function Checkbox({
52
55
  style={styles.input}
53
56
  />
54
57
  <html.span
55
- style={[styles.box, isChecked ? styles.boxChecked : styles.boxUnchecked]}
58
+ style={[
59
+ styles.box,
60
+ isNative && styles.nativeFlex,
61
+ isChecked ? styles.boxChecked : styles.boxUnchecked,
62
+ ]}
56
63
  aria-hidden
57
64
  >
58
65
  <svg
@@ -54,4 +54,9 @@ export const styles = css.create({
54
54
  opacity: 0,
55
55
  overflow: 'hidden',
56
56
  },
57
+ // RSD-native only honors display:'flex' (not 'inline-flex'). Layered on
58
+ // native via `isNative` (on both .root and .box); web keeps inline-flex.
59
+ nativeFlex: {
60
+ display: 'flex',
61
+ },
57
62
  })
@@ -1,6 +1,7 @@
1
1
  import type {ReactNode} from 'react'
2
2
  import {useMemo} from 'react'
3
3
  import {css, html} from 'react-strict-dom'
4
+ import {isNative} from '../../platform'
4
5
  import {InputGroupContext} from './InputGroupContext'
5
6
  import {styles} from './styles.css'
6
7
 
@@ -37,6 +38,7 @@ function Addon({position = 'end', onClick, disabled, minWidth, children}: AddonP
37
38
  const positionStyle = position === 'start' ? styles.addonStart : styles.addonEnd
38
39
  const style = [
39
40
  styles.addon,
41
+ isNative && styles.nativeFlex,
40
42
  positionStyle,
41
43
  onClick && !disabled && styles.addonClickable,
42
44
  disabled && styles.addonDisabled,
@@ -58,4 +58,9 @@ export const styles = css.create({
58
58
  opacity: 0.4,
59
59
  cursor: 'not-allowed',
60
60
  },
61
+ // RSD-native only honors display:'flex' (not 'inline-flex'). Layered on
62
+ // native via `isNative` so the flex container applies; web keeps inline-flex.
63
+ nativeFlex: {
64
+ display: 'flex',
65
+ },
61
66
  })
@@ -1,5 +1,6 @@
1
1
  import {type ReactNode, useCallback, useRef} from 'react'
2
2
  import {html} from 'react-strict-dom'
3
+ import {isNative} from '../../platform'
3
4
  import {useControllableValue} from '../../hooks/useControllableValue'
4
5
  import {styles} from './styles.css'
5
6
 
@@ -46,7 +47,9 @@ export function Switch({
46
47
  }, [disabled, checked, setChecked])
47
48
 
48
49
  return (
49
- <html.label style={[styles.root, disabled && styles.rootDisabled]}>
50
+ <html.label
51
+ style={[styles.root, isNative && styles.nativeFlex, disabled && styles.rootDisabled]}
52
+ >
50
53
  <html.input
51
54
  ref={inputRef}
52
55
  type="checkbox"
@@ -68,4 +68,9 @@ export const styles = css.create({
68
68
  opacity: 0,
69
69
  overflow: 'hidden',
70
70
  },
71
+ // RSD-native only honors display:'flex' (not 'inline-flex'). Layered on
72
+ // native via `isNative` so the flex container applies; web keeps inline-flex.
73
+ nativeFlex: {
74
+ display: 'flex',
75
+ },
71
76
  })
@@ -0,0 +1,49 @@
1
+ // Native (React Native / Expo) ThemeProvider — Metro resolves this over
2
+ // ThemeProvider.tsx via the platform extension. The web version uses
3
+ // `display:contents` + a fixed portal-mount, neither of which exists on RN, so
4
+ // this applies the theme StyleX styles to a plain flex-column container and
5
+ // drops the portal mount (native overlays don't portal to a fixed div).
6
+ import {createContext, type ReactNode, useContext} from 'react'
7
+ import {css, html} from 'react-strict-dom'
8
+ import {colors} from '@duro-app/tokens/tokens/colors.css'
9
+ import {lightTheme, lightShadows} from '@duro-app/tokens/themes/light.css'
10
+ import {highContrastTheme, highContrastShadows} from '@duro-app/tokens/themes/high-contrast.css'
11
+
12
+ export type ThemeName = 'dark' | 'light' | 'high-contrast'
13
+
14
+ interface ThemeProviderProps {
15
+ theme?: ThemeName
16
+ children: ReactNode
17
+ }
18
+
19
+ const themeMap: Partial<Record<ThemeName, readonly [typeof lightTheme, typeof lightShadows]>> = {
20
+ light: [lightTheme, lightShadows],
21
+ 'high-contrast': [highContrastTheme, highContrastShadows],
22
+ }
23
+
24
+ const styles = css.create({
25
+ // No `display:contents` on RN. RSD uses web flex semantics on native, so
26
+ // declare flex + column explicitly; flex:1 lets a root provider fill.
27
+ root: {
28
+ display: 'flex',
29
+ flexDirection: 'column',
30
+ flex: 1,
31
+ color: colors.text,
32
+ },
33
+ })
34
+
35
+ type DivStyle = Parameters<typeof html.div>[0]['style']
36
+
37
+ // Parity with the web export — there's no portal mount on native, so this is
38
+ // always null. (The components that consume it aren't in the native barrel.)
39
+ const PortalMountContext = createContext<HTMLElement | null>(null)
40
+
41
+ export function usePortalMount(): HTMLElement | null {
42
+ return useContext(PortalMountContext)
43
+ }
44
+
45
+ export function ThemeProvider({theme = 'dark', children}: ThemeProviderProps) {
46
+ const overrides = themeMap[theme]
47
+ const themeStyles = [overrides?.[0], overrides?.[1], styles.root] as DivStyle
48
+ return <html.div style={themeStyles}>{children}</html.div>
49
+ }
@@ -34,3 +34,11 @@ export {Stack, type SpacingKey} from './components/Stack/Stack'
34
34
  export {Inline} from './components/Inline/Inline'
35
35
  export {Cluster} from './components/Cluster/Cluster'
36
36
  export {Grid} from './components/Grid/Grid'
37
+
38
+ // Theming — resolves to ThemeProvider.native.tsx on Metro (RN-safe variant:
39
+ // no display:contents / portal mount; applies the theme to a flex container).
40
+ export {
41
+ ThemeProvider,
42
+ usePortalMount,
43
+ type ThemeName,
44
+ } from './components/ThemeProvider/ThemeProvider'
@@ -0,0 +1,3 @@
1
+ // Native (React Native / Expo) counterpart of platform.ts — Metro resolves
2
+ // this over platform.ts via the platform extension. See platform.ts.
3
+ export const isNative: boolean = true
@@ -0,0 +1,11 @@
1
+ /**
2
+ * Platform flag resolved by the bundler's platform extensions: web bundlers
3
+ * (Vite/Rollup) read THIS file (`isNative = false`); Metro reads
4
+ * `platform.native.ts` (`isNative = true`) on React Native / Expo.
5
+ *
6
+ * It lets shared components layer a native-only style override without
7
+ * importing `react-native` on web (the DS web build has no react-native).
8
+ * Typed `boolean` (not the `false` literal) so `isNative && styles.x` stays a
9
+ * `false | Style` union in style arrays rather than narrowing to `false`.
10
+ */
11
+ export const isNative: boolean = false