phoenix_duskmoon 10.0.10 → 10.0.12

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/CHANGELOG.md CHANGED
@@ -1,3 +1,23 @@
1
+ # [10.0.12](https://github.com/duskmoon-dev/phoenix-duskmoon-ui/compare/v10.0.11...v10.0.12) (2026-11-01)
2
+
3
+ ### Fixed
4
+
5
+ - Exclude build-tool applications (`duskmoon_npm`, `duskmoon_hex_solver`, etc.) from
6
+ Storybook production release assembly, ensuring a clean runtime-only release.
7
+ - Add Bun setup to test workflow for browser component tests.
8
+ - Bump `@duskmoon-dev/components` to 0.5.5 for Popover API support, dropdown select
9
+ layout, and timeline marker styling.
10
+
11
+ # [10.0.11](https://github.com/duskmoon-dev/phoenix-duskmoon-ui/compare/v10.0.10...v10.0.11) (2026-10-22)
12
+
13
+ ### Fixed
14
+
15
+ - Synchronize native dropdown triggers' explicit `aria-expanded` state on open,
16
+ Escape, light dismiss and LiveView patches through the existing CSP-safe
17
+ `DuskmoonPopover` hook. Preserve native-only behavior and accessibility when
18
+ the hook is absent, resolving
19
+ [#209](https://github.com/duskmoon-dev/phoenix-duskmoon-ui/issues/209).
20
+
1
21
  # [10.0.10](https://github.com/duskmoon-dev/phoenix-duskmoon-ui/compare/v10.0.9...v10.0.10) (2026-10-22)
2
22
 
3
23
  ### Fixed
package/README.md CHANGED
@@ -32,13 +32,13 @@ Add to `mix.exs`:
32
32
  Install frontend packages:
33
33
 
34
34
  ```bash
35
- bun add @duskmoon-dev/core @duskmoon-dev/elements
35
+ mix npm.install @duskmoon-dev/core @duskmoon-dev/elements
36
36
  ```
37
37
 
38
38
  Optionally, add CSS Art and Art Custom Elements support:
39
39
 
40
40
  ```bash
41
- bun add @duskmoon-dev/css-art @duskmoon-dev/art-elements
41
+ mix npm.install @duskmoon-dev/css-art @duskmoon-dev/art-elements
42
42
  ```
43
43
 
44
44
  ### View Helpers
@@ -189,12 +189,19 @@ application's upload mechanism; they cannot be sent as LiveView JSON payloads.
189
189
  ## Repository development
190
190
 
191
191
  This checkout contains the UI and Storybook. It consumes the published toolchain
192
- cohort pinned in `BUNDLER_VERSION` and `mix.lock`; ordinary UI builds use verified
193
- precompiled Duskmoon native artifacts. The toolchain source and its own releases
194
- live in [duskmoon-bundler](https://github.com/duskmoon-dev/duskmoon-bundler).
192
+ cohort declared with `~> 10.0` requirements and resolved in `mix.lock`; ordinary UI
193
+ builds use verified precompiled Duskmoon native artifacts. The toolchain source
194
+ and its own releases live in [duskmoon-bundler](https://github.com/duskmoon-dev/duskmoon-bundler).
195
195
  See the [migration and development guide](docs/bundler-extraction.md) for setup,
196
196
  candidate integration and independent release order.
197
197
 
198
+ Storybook also consumes `duskmoon_hologram ~> 10.0` and provides a Hologram section
199
+ before Storybook in its top navigation. Run `mix duskmoon.dev` (or `mix holo`) and
200
+ open `/hologram` for the component playground, task list and profile preview.
201
+ The checkout requires OTP 28+; `phoenix_duskmoon` itself keeps its existing Elixir
202
+ and Phoenix compatibility and does not depend on Hologram. See the
203
+ [Hologram guide](docs/hologram-example.md) for runtime boundaries and verification.
204
+
198
205
  ## Live Storybook
199
206
 
200
207
  [Live Storybook](https://duskmoon-storybook.gsmlg.dev)
@@ -10,12 +10,55 @@ export function syncPopoverState(element) {
10
10
  if (controlledOpen === "false" && open) element.hidePopover();
11
11
  }
12
12
 
13
+ // Dropdown hooks live on the wrapper so patches to either the trigger or panel
14
+ // resynchronize state. Existing popover hooks still mount directly on the panel.
15
+ function hookPopover(element) {
16
+ return element.dataset.popoverId
17
+ ? element.ownerDocument.getElementById(element.dataset.popoverId)
18
+ : element;
19
+ }
20
+
21
+ function syncExpandedState(element, popover) {
22
+ if (element === popover || !("showPopover" in popover)) return;
23
+
24
+ const expanded = String(popover.matches(":popover-open"));
25
+
26
+ for (const trigger of element.querySelectorAll("[aria-controls]")) {
27
+ if (trigger.getAttribute("aria-controls") === popover.id) {
28
+ trigger.setAttribute("aria-expanded", expanded);
29
+ }
30
+ }
31
+ }
32
+
33
+ function syncHookState(hook) {
34
+ const popover = hookPopover(hook.el);
35
+
36
+ if (hook._popover !== popover) {
37
+ hook._popover?.removeEventListener("toggle", hook._onPopoverToggle);
38
+ hook._popover = popover;
39
+ popover?.addEventListener("toggle", hook._onPopoverToggle);
40
+ }
41
+
42
+ if (!popover) return;
43
+
44
+ syncPopoverState(popover);
45
+ syncExpandedState(hook.el, popover);
46
+ }
47
+
13
48
  export const DuskmoonPopover = {
14
49
  mounted() {
15
- syncPopoverState(this.el);
50
+ this._onPopoverToggle = () => {
51
+ if (this._popover) syncExpandedState(this.el, this._popover);
52
+ };
53
+ syncHookState(this);
16
54
  },
17
55
 
18
56
  updated() {
19
- syncPopoverState(this.el);
57
+ syncHookState(this);
58
+ },
59
+
60
+ destroyed() {
61
+ this._popover?.removeEventListener("toggle", this._onPopoverToggle);
62
+ this._popover = null;
20
63
  },
21
64
  };
@@ -48,7 +48,7 @@ export declare const Spotlight: LiveViewHook<HTMLDialogElement>;
48
48
  /** Page-header visibility observer. */
49
49
  export declare const PageHeader: LiveViewHook;
50
50
 
51
- /** Synchronizes an explicitly controlled native popover with LiveView state. */
51
+ /** Synchronizes native dropdown expanded state and optional server-controlled popover visibility. */
52
52
  export declare const DuskmoonPopover: LiveViewHook<HTMLElement>;
53
53
 
54
54
  /** Preserves left-menu collapse, group, and scroll state across LiveView patches. */
@@ -22,7 +22,7 @@
22
22
  * - ThemeSwitcher: Theme toggle with localStorage persistence
23
23
  * - Spotlight: Keyboard shortcut (Cmd/Ctrl+K) for spotlight search
24
24
  * - PageHeader: Intersection observer for scroll-based effects
25
- * - DuskmoonPopover: Optional server-controlled native popover state
25
+ * - DuskmoonPopover: Native dropdown expanded state and optional server-controlled popovers
26
26
  * - DuskmoonLeftMenu: Collapsible sidebar with persistent group and scroll state
27
27
  * - DuskmoonLeftMenuNavigation: Active-page synchronization for sticky left menus
28
28
  * - DuskmoonSplitPane: Accessible client-owned split-pane resizing
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "phoenix_duskmoon",
3
- "version": "10.0.10",
3
+ "version": "10.0.12",
4
4
  "type": "module",
5
5
  "exports": {
6
6
  ".": "./priv/static/assets/js/phoenix_duskmoon.js",
@@ -37,18 +37,18 @@
37
37
  "registry": "https://registry.npmjs.org/"
38
38
  },
39
39
  "dependencies": {
40
- "@duskmoon-dev/art-elements": "1.9.3",
41
- "@duskmoon-dev/components": "0.5.2",
42
- "@duskmoon-dev/core": "1.20.6",
43
- "@duskmoon-dev/css-art": "1.20.6",
44
- "@duskmoon-dev/elements": "1.9.3",
45
- "react": "19.3.0",
46
- "react-dom": "19.3.0"
40
+ "@duskmoon-dev/art-elements": "1.10.2",
41
+ "@duskmoon-dev/components": "0.5.5",
42
+ "@duskmoon-dev/core": "1.20.8",
43
+ "@duskmoon-dev/css-art": "1.20.8",
44
+ "@duskmoon-dev/elements": "1.10.2",
45
+ "react": "19.3.1",
46
+ "react-dom": "19.3.1"
47
47
  },
48
48
  "devDependencies": {
49
49
  "@mdi/svg": "7.4.47",
50
50
  "bootstrap-icons": "1.13.2",
51
- "postcss": "8.5.29"
51
+ "postcss": "8.5.32"
52
52
  },
53
53
  "peerDependencies": {
54
54
  "tailwindcss": "^4.3.2"