@codecademy/gamut-styles 17.13.2-alpha.d5be1a.0 → 17.13.2-alpha.d74f60.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.
@@ -0,0 +1,32 @@
1
+ import type { RefObject } from 'react';
2
+ /**
3
+ * Resolved HTML `dir` keyword: effective writing direction after `dir`, then CSS
4
+ * `direction`, then document root.
5
+ */
6
+ export type DirValue = 'rtl' | 'ltr';
7
+ /**
8
+ * Resolves the effective `dir` for an element (`rtl` or `ltr`), including JSDOM where
9
+ * `getComputedStyle(el).direction` is often empty while `dir` is set on the root.
10
+ *
11
+ * @param el - DOM node whose effective direction is resolved.
12
+ * @returns `rtl` or `ltr`.
13
+ */
14
+ export declare function elementDir(el: Element): DirValue;
15
+ /**
16
+ * Ref whose `current` may be any DOM {@link Element} subclass (`HTMLElement`, `SVGElement`,
17
+ * `HTMLButtonElement`, etc.). For structural/minimal types (e.g. tests), intersect with
18
+ * `Element` so `current` is still typed as an `Element` (e.g. `Pick<HTMLAnchorElement, 'id'> & Element`).
19
+ *
20
+ * @template T - DOM element type for `current`; defaults to {@link Element}.
21
+ */
22
+ export type ElementDirRef<T extends Element = Element> = RefObject<T | null>;
23
+ /**
24
+ * Returns the effective `dir` for the resolved element (`rtl` or `ltr`), and updates when `dir`
25
+ * changes on the document subtree or after layout (so `ref.current` is current).
26
+ * Resolution uses {@link elementDir}.
27
+ *
28
+ * @template T - DOM element type for the optional ref; defaults to {@link Element}.
29
+ * @param elementRef - Optional ref; when missing or `current` is not an `Element`, uses `document.documentElement`.
30
+ * @returns Effective direction for the resolved element, or `ltr` when `document` is undefined (SSR).
31
+ */
32
+ export declare function useElementDir<T extends Element = Element>(elementRef?: ElementDirRef<T>): DirValue;
@@ -0,0 +1,69 @@
1
+ import { useEffect, useLayoutEffect, useReducer } from 'react';
2
+
3
+ /**
4
+ * Resolved HTML `dir` keyword: effective writing direction after `dir`, then CSS
5
+ * `direction`, then document root.
6
+ */
7
+
8
+ /**
9
+ * Resolves the effective `dir` for an element (`rtl` or `ltr`), including JSDOM where
10
+ * `getComputedStyle(el).direction` is often empty while `dir` is set on the root.
11
+ *
12
+ * @param el - DOM node whose effective direction is resolved.
13
+ * @returns `rtl` or `ltr`.
14
+ */
15
+ export function elementDir(el) {
16
+ const ownDir = el.getAttribute('dir');
17
+ if (ownDir === 'rtl') return 'rtl';
18
+ if (ownDir === 'ltr') return 'ltr';
19
+ const {
20
+ direction
21
+ } = getComputedStyle(el);
22
+ if (direction === 'rtl' || direction === 'ltr') {
23
+ return direction;
24
+ }
25
+ return document.documentElement.getAttribute('dir') === 'rtl' ? 'rtl' : 'ltr';
26
+ }
27
+
28
+ /**
29
+ * Ref whose `current` may be any DOM {@link Element} subclass (`HTMLElement`, `SVGElement`,
30
+ * `HTMLButtonElement`, etc.). For structural/minimal types (e.g. tests), intersect with
31
+ * `Element` so `current` is still typed as an `Element` (e.g. `Pick<HTMLAnchorElement, 'id'> & Element`).
32
+ *
33
+ * @template T - DOM element type for `current`; defaults to {@link Element}.
34
+ */
35
+
36
+ function resolveElement(elementRef) {
37
+ return elementRef?.current instanceof Element ? elementRef.current : document.documentElement;
38
+ }
39
+
40
+ /**
41
+ * Returns the effective `dir` for the resolved element (`rtl` or `ltr`), and updates when `dir`
42
+ * changes on the document subtree or after layout (so `ref.current` is current).
43
+ * Resolution uses {@link elementDir}.
44
+ *
45
+ * @template T - DOM element type for the optional ref; defaults to {@link Element}.
46
+ * @param elementRef - Optional ref; when missing or `current` is not an `Element`, uses `document.documentElement`.
47
+ * @returns Effective direction for the resolved element, or `ltr` when `document` is undefined (SSR).
48
+ */
49
+ export function useElementDir(elementRef) {
50
+ const [, bump] = useReducer(n => n + 1, 0);
51
+ useLayoutEffect(() => {
52
+ bump();
53
+ }, [elementRef]);
54
+ useEffect(() => {
55
+ const observer = new MutationObserver(() => {
56
+ bump();
57
+ });
58
+ observer.observe(document.documentElement, {
59
+ attributeFilter: ['dir'],
60
+ attributes: true,
61
+ subtree: true
62
+ });
63
+ return () => observer.disconnect();
64
+ }, []);
65
+ if (typeof document === 'undefined') {
66
+ return 'ltr';
67
+ }
68
+ return elementDir(resolveElement(elementRef));
69
+ }
@@ -1,3 +1,3 @@
1
- export * from './directionIsRtl';
1
+ export * from './elementDir';
2
2
  export * from './themed';
3
3
  export * from './useLogicalProperties';
@@ -1,3 +1,3 @@
1
- export * from './directionIsRtl';
1
+ export * from './elementDir';
2
2
  export * from './themed';
3
3
  export * from './useLogicalProperties';
@@ -1,8 +1,7 @@
1
1
  /**
2
- * Whether Gamut system props emit logical CSS properties (`marginInlineStart`, etc.)
3
- * vs physical (`marginLeft`, etc.). Matches `@codecademy/variance` when the theme
4
- * omits the field: `theme.useLogicalProperties ?? true`.
2
+ * Whether Gamut system props map to logical CSS properties (`marginInlineStart`, etc.)
3
+ * vs physical (`marginLeft`, etc.).
5
4
  *
6
5
  * `GamutProvider` always merges an explicit boolean (default `false`).
7
6
  */
8
- export declare function useLogicalProperties(): boolean;
7
+ export declare function useLogicalProperties(): boolean | undefined;
@@ -1,13 +1,12 @@
1
1
  import { useTheme } from '@emotion/react';
2
2
 
3
3
  /**
4
- * Whether Gamut system props emit logical CSS properties (`marginInlineStart`, etc.)
5
- * vs physical (`marginLeft`, etc.). Matches `@codecademy/variance` when the theme
6
- * omits the field: `theme.useLogicalProperties ?? true`.
4
+ * Whether Gamut system props map to logical CSS properties (`marginInlineStart`, etc.)
5
+ * vs physical (`marginLeft`, etc.).
7
6
  *
8
7
  * `GamutProvider` always merges an explicit boolean (default `false`).
9
8
  */
10
9
  export function useLogicalProperties() {
11
10
  const theme = useTheme();
12
- return theme.useLogicalProperties ?? true;
11
+ return theme?.useLogicalProperties;
13
12
  }
package/package.json CHANGED
@@ -1,10 +1,10 @@
1
1
  {
2
2
  "name": "@codecademy/gamut-styles",
3
3
  "description": "Styleguide & Component library for codecademy.com",
4
- "version": "17.13.2-alpha.d5be1a.0",
4
+ "version": "17.13.2-alpha.d74f60.0",
5
5
  "author": "Jake Hiller <jake@codecademy.com>",
6
6
  "dependencies": {
7
- "@codecademy/variance": "0.26.2-alpha.d5be1a.0",
7
+ "@codecademy/variance": "0.26.2-alpha.d74f60.0",
8
8
  "@emotion/is-prop-valid": "^1.1.0",
9
9
  "framer-motion": "^11.18.0",
10
10
  "get-nonce": "^1.0.0",
@@ -1,14 +0,0 @@
1
- import type { RefObject } from 'react';
2
- /**
3
- * Resolves whether layout direction is RTL for an element, including JSDOM where
4
- * `getComputedStyle(el).direction` is often empty while `dir` is set on the root.
5
- */
6
- export declare function directionIsRtl(el: Element): boolean;
7
- /**
8
- * Returns whether the resolved element’s direction is RTL, and updates when `dir`
9
- * changes on the document subtree or after layout (so `ref.current` is current).
10
- * Resolution uses {@link directionIsRtl}.
11
- *
12
- * @param elementRef - Optional ref; when missing or `current` is not an `Element`, uses `document.documentElement`.
13
- */
14
- export declare function useDirectionIsRtl(elementRef?: RefObject<Element | null>): boolean;
@@ -1,50 +0,0 @@
1
- import { useEffect, useLayoutEffect, useReducer } from 'react';
2
-
3
- /**
4
- * Resolves whether layout direction is RTL for an element, including JSDOM where
5
- * `getComputedStyle(el).direction` is often empty while `dir` is set on the root.
6
- */
7
- export function directionIsRtl(el) {
8
- const ownDir = el.getAttribute('dir');
9
- if (ownDir === 'rtl') return true;
10
- if (ownDir === 'ltr') return false;
11
- const {
12
- direction
13
- } = getComputedStyle(el);
14
- if (direction === 'rtl' || direction === 'ltr') {
15
- return direction === 'rtl';
16
- }
17
- return document.documentElement.getAttribute('dir') === 'rtl';
18
- }
19
- function resolveElement(elementRef) {
20
- return elementRef?.current instanceof Element ? elementRef.current : document.documentElement;
21
- }
22
-
23
- /**
24
- * Returns whether the resolved element’s direction is RTL, and updates when `dir`
25
- * changes on the document subtree or after layout (so `ref.current` is current).
26
- * Resolution uses {@link directionIsRtl}.
27
- *
28
- * @param elementRef - Optional ref; when missing or `current` is not an `Element`, uses `document.documentElement`.
29
- */
30
- export function useDirectionIsRtl(elementRef) {
31
- const [, bump] = useReducer(n => n + 1, 0);
32
- useLayoutEffect(() => {
33
- bump();
34
- }, [elementRef]);
35
- useEffect(() => {
36
- const observer = new MutationObserver(() => {
37
- bump();
38
- });
39
- observer.observe(document.documentElement, {
40
- attributeFilter: ['dir'],
41
- attributes: true,
42
- subtree: true
43
- });
44
- return () => observer.disconnect();
45
- }, []);
46
- if (typeof document === 'undefined') {
47
- return false;
48
- }
49
- return directionIsRtl(resolveElement(elementRef));
50
- }