@nysds/components 1.16.0-alpha-3 → 1.16.0-alpha4

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.
@@ -159,7 +159,6 @@ export declare class NysButton extends LitElement {
159
159
  * @default "_self"
160
160
  */
161
161
  target: "_self" | "_blank" | "_parent" | "_top" | "framename";
162
- getButtonElement(): Promise<HTMLElement | null>;
163
162
  private _internals;
164
163
  /**
165
164
  * Lifecycle methods
@@ -183,10 +182,14 @@ export declare class NysButton extends LitElement {
183
182
  private _handleClick;
184
183
  private _handleKeydown;
185
184
  /**
186
- * Vanilla JS & Native HTML keydown solution:
187
- * The <nys-button onClick="doFunction();"></nys-button> onClick is an attribute here.
188
- * Thus, we call it here. Otherwise, at this point, this.onClick is null as it isn't props, but a string attribute
189
- * In vanilla HTML/JS, clicking with execute the attribute function, BUT now with keydown, hence this solution.
185
+ * A Solution to the Vanilla JS & Native HTML keydown:
186
+ *
187
+ * Handles inline onClick attributes set as strings in vanilla HTML
188
+ * (e.g. <nys-button onClick="doSomething()">).
189
+ *
190
+ * When onClick is set this way, it is a DOM attribute (not a property)
191
+ * so this.onClick remains null. Native clicks execute the attribute
192
+ * automatically, but keydown events do not, so we invoke it manually here.
190
193
  */
191
194
  private _handleAnyAttributeFunction;
192
195
  focus(options?: FocusOptions): void;
@@ -97,6 +97,7 @@ export declare class NysCheckboxgroup extends LitElement {
97
97
  private _handleCheckboxChange;
98
98
  private _handleChildError;
99
99
  private _handleChildErrorClear;
100
+ private _handleOtherInput;
100
101
  private _checkOtherInputs;
101
102
  render(): import("lit-html").TemplateResult<1>;
102
103
  }
@@ -25,8 +25,10 @@ export declare class NysGlobalHeader extends LitElement {
25
25
  agencyName: string;
26
26
  /** URL for the header title link. If empty, title is not clickable. */
27
27
  homepageLink: string;
28
- private isMobileMenuOpen;
29
- private hasLinkContent;
28
+ /** Internal state to track mobile menu open/closed status. */
29
+ private _isMobileMenuOpen;
30
+ /** Internal state to track if any navigation links are present in the slot. */
31
+ private _hasLinkContent;
30
32
  /**
31
33
  * Lifecycle Methods
32
34
  * --------------------------------------------------------------------------
@@ -81,6 +81,7 @@ export declare class NysRadiobutton extends LitElement {
81
81
  formResetUpdate(): void;
82
82
  private _handleResize;
83
83
  private _clearOtherState;
84
+ private _dispatchClearErrorEvent;
84
85
  /**
85
86
  * Event Handlers
86
87
  * --------------------------------------------------------------------------
@@ -104,5 +104,7 @@ export declare class NysRadiogroup extends LitElement {
104
104
  private _handleRadioButtonChange;
105
105
  private _handleInvalid;
106
106
  private _handleChildError;
107
+ private _handleChildErrorClear;
108
+ private _handleOtherInput;
107
109
  render(): import("lit-html").TemplateResult<1>;
108
110
  }
@@ -6,6 +6,8 @@ import { LitElement } from "lit";
6
6
  * @slot - Accepts a `<table>` element. Only the first table is rendered.
7
7
  *
8
8
  * @fires nys-click - Fired when the download button or sortable headers are clicked.
9
+ * @fires nys-column-sort - Fired when a sortable column header is clicked. Can be prevented by calling `event.preventDefault()` to override default sort behavior.
10
+ * Detail: { columnIndex: number, columnLabel: string, sortDirection: "asc" | "desc" | "none" }
9
11
  *
10
12
  * @method downloadFile - Triggers download of the CSV file if `download` is set.
11
13
  */
@@ -30,10 +32,19 @@ export declare class NysTable extends LitElement {
30
32
  willUpdate(): void;
31
33
  _addSortIcons(table: HTMLTableElement): void;
32
34
  _updateSortIcons(table: HTMLTableElement): void;
33
- _onSortClick(columnIndex: number, table: HTMLTableElement): void;
35
+ private _onSortClick;
34
36
  _sortTable(table: HTMLTableElement, columnIndex: number, direction: "asc" | "desc"): void;
35
37
  _updateSortedColumnStyles(table: HTMLTableElement): void;
36
38
  downloadFile(): void;
37
39
  /****************** Event Handlers ******************/
40
+ /**
41
+ * Dispatches the `nys-column-sort` custom event.
42
+ *
43
+ * @param columnIndex - Zero-based index of the sorted column.
44
+ * @param columnLabel - The text label of the sorted column header.
45
+ * @param sortDirection - The new sort direction: "asc", "desc", or "none".
46
+ */
47
+ private _emitColumnSortEvent;
48
+ /****************** Render ******************/
38
49
  render(): import("lit-html").TemplateResult<1>;
39
50
  }
@@ -1,4 +1,10 @@
1
1
  import { LitElement } from "lit";
2
+ declare global {
3
+ interface Window {
4
+ YT: any;
5
+ onYouTubeIframeAPIReady: () => void;
6
+ }
7
+ }
2
8
  export declare class NysVideo extends LitElement {
3
9
  static styles: import("lit").CSSResult;
4
10
  /** Full YouTube URL — required. Component will not render if invalid. */
@@ -11,7 +17,7 @@ export declare class NysVideo extends LitElement {
11
17
  * Largest size for the video player.
12
18
  * If not set, size is determined automatically by viewport width.
13
19
  */
14
- size: "full" | "contained" | "compacted" | "";
20
+ size: "full" | "md" | "sm" | "";
15
21
  loading: "lazy" | "eager";
16
22
  /** Time in seconds where playback begins. **/
17
23
  starttime: number;
@@ -26,11 +32,10 @@ export declare class NysVideo extends LitElement {
26
32
  disabled: boolean;
27
33
  /** Tracks whether the user has clicked to load the player */
28
34
  private _playerActive;
29
- /** Auto-computed size when no explicit size prop is set */
30
- private _autoSize;
31
- private _mediaFull;
32
- private _mediaMobileLarge;
33
- private _onMediaChange;
35
+ /** Screen reader announcement text */
36
+ private _announcement;
37
+ /** Tracks whether an ad is currently playing to suppress false "Video is playing" announcements */
38
+ private _adPlaying;
34
39
  constructor();
35
40
  connectedCallback(): void;
36
41
  disconnectedCallback(): void;
@@ -38,15 +43,29 @@ export declare class NysVideo extends LitElement {
38
43
  * Functions
39
44
  * --------------------------------------------------------------------------
40
45
  */
41
- private _updateAutoSize;
42
46
  private _isValidYouTubeUrl;
43
47
  private _getVideoId;
44
48
  private _getThumbnailUrl;
45
49
  private _getEmbedUrl;
50
+ /**
51
+ * Because I need to know if Youtube ADs are playing, I need to call YT's API.
52
+ * Hence, the YT API setup below. The VO has 2 types of announcements:
53
+ * - "Advertisement is playing"
54
+ * - "Video is playing"
55
+ *
56
+ * YT IFrame Player API: https://developers.google.com/youtube/iframe_api_reference
57
+ */
58
+ private _announceVideoVO;
46
59
  /**
47
60
  * Event Handlers
48
61
  * --------------------------------------------------------------------------
49
62
  */
50
63
  private _handleThumbnailClick;
64
+ /**
65
+ * Render Helpers
66
+ * --------------------------------------------------------------------------
67
+ */
68
+ private _renderAnnouncer;
69
+ private _renderPlayIcon;
51
70
  render(): import("lit-html").TemplateResult<1>;
52
71
  }
@@ -28,3 +28,4 @@ export * from "../packages/nys-unavheader/src/index";
28
28
  export * from "../packages/nys-globalheader/src/index";
29
29
  export * from "../packages/nys-globalfooter/src/index";
30
30
  export * from "../packages/nys-unavfooter/src/index";
31
+ export * from "../packages/nys-video/src/index";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nysds/components",
3
- "version": "1.16.0-alpha-3",
3
+ "version": "1.16.0-alpha4",
4
4
  "description": "New York State's design system and code component library.",
5
5
  "type": "module",
6
6
  "workspaces": [
@@ -32,16 +32,17 @@
32
32
  "build": "tsc --emitDeclarationOnly && vite build",
33
33
  "build:umd": "cross-env BUILD_FORMAT=umd vite build",
34
34
  "tsc:packages": "tsc -b tsconfig.build.json",
35
- "build:packages": "npm run tsc:packages && turbo run build --filter='./packages/*'",
35
+ "build:packages": "npm run tsc:packages && turbo run build --filter='./packages/*' --log-order=grouped",
36
36
  "build:root": "cross-env NODE_ENV=production npm run build && cross-env NODE_ENV=production npm run build:umd",
37
- "build:all": "npm run clean:dist && npm run lint && npm run lit-analyze || true&& cross-env NODE_ENV=production npm run build:packages && npm run build:root && npm run cem && npm run mcp-server:build",
38
- "build:link": "npm run build:all && npm link",
37
+ "build:all": "npm run clean:dist && npm run lint && npm run lit-analyze || true && cross-env NODE_ENV=production npm run build:packages && npm run build:root && npm run cem && npm run mcp-server:build",
38
+ "build:link": "npm run build:all && npm link && cd packages/styles && npm link",
39
39
  "lint": "eslint --cache --cache-location node_modules/.cache/eslint && stylelint **/*.scss || true",
40
40
  "lint:fix": "eslint --fix && stylelint **/*.scss --fix",
41
41
  "lit-analyze": "find ./packages/nys-*/ -name '*.ts' ! -name '*.figma.*' | xargs lit-analyzer {}",
42
42
  "release": "cross-env NODE_ENV=production npm run build:all && cross-env NODE_ENV=production npm run test && npm run cem && cross-env NODE_ENV=production npm publish --workspaces --access public && cross-env NODE_ENV=production npm publish --access public",
43
43
  "release:dry-run": "cross-env NODE_ENV=production npm run build:all && cross-env NODE_ENV=production npm run test && npm run cem && node src/scripts/publish-dry-run.js",
44
- "release:alpha": "npm run build && npm run build:umd && npm publish --tag next",
44
+ "release:alpha": "cross-env NODE_ENV=production npm run build:all && cross-env NODE_ENV=production npm run test && npm run cem && cross-env NODE_ENV=production npm publish --workspaces --access public --tag next && cross-env NODE_ENV=production npm publish --access public --tag next",
45
+ "release:zip": "npm run build:all && node src/scripts/create-release-zip.js",
45
46
  "test": "npx playwright install && wtr --node-resolve",
46
47
  "test:build": "npm run build:all && npm run test",
47
48
  "storybook": "cross-env NODE_ENV=production storybook dev -p 6006",
@@ -106,8 +107,8 @@
106
107
  "stylelint-config-standard": "^40.0.0",
107
108
  "stylelint-config-standard-scss": "^17.0.0",
108
109
  "tslib": "^2.8.1",
110
+ "turbo": "^2.8.20",
109
111
  "typescript": "^5.9.3",
110
- "turbo": "^2.8.16",
111
112
  "vite": "^7.3.1"
112
113
  },
113
114
  "eslintConfig": {
@@ -59,6 +59,9 @@ export interface NysTableProps extends Pick<
59
59
 
60
60
  /** Fired when the download button or sortable headers are clicked. */
61
61
  onNysClick?: (event: CustomEvent) => void;
62
+
63
+ /** Fired when a sortable column header is clicked. Can be prevented by calling `event.preventDefault()` to override default sort behavior. Detail: { columnIndex: number, columnLabel: string, sortDirection: "asc" | "desc" | "none" } */
64
+ onNysColumnSort?: (event: CustomEvent) => void;
62
65
  }
63
66
 
64
67
  /**
@@ -69,6 +72,7 @@ export interface NysTableProps extends Pick<
69
72
  *
70
73
  * ### **Events:**
71
74
  * - **nys-click** - Fired when the download button or sortable headers are clicked.
75
+ * - **nys-column-sort** - Fired when a sortable column header is clicked. Can be prevented by calling `event.preventDefault()` to override default sort behavior. Detail: { columnIndex: number, columnLabel: string, sortDirection: "asc" | "desc" | "none" }
72
76
  *
73
77
  * ### **Slots:**
74
78
  * - _default_ - Accepts a `<table>` element. Only the first table is rendered.
@@ -9,6 +9,7 @@ export const NysTable = forwardRef((props, forwardedRef) => {
9
9
 
10
10
  /** Event listeners - run once */
11
11
  useEventListener(ref, "nys-click", props.onNysClick);
12
+ useEventListener(ref, "nys-column-sort", props.onNysColumnSort);
12
13
 
13
14
  return React.createElement(
14
15
  "nys-table",
@@ -0,0 +1,77 @@
1
+ import React from "react";
2
+ import { NysVideo as NysVideoElement } from "../../dist/nysds.es.js";
3
+
4
+ export type { NysVideoElement };
5
+
6
+ export interface NysVideoProps extends Pick<
7
+ React.AllHTMLAttributes<HTMLElement>,
8
+ | "children"
9
+ | "dir"
10
+ | "hidden"
11
+ | "id"
12
+ | "lang"
13
+ | "slot"
14
+ | "style"
15
+ | "title"
16
+ | "translate"
17
+ | "onClick"
18
+ | "onFocus"
19
+ | "onBlur"
20
+ > {
21
+ /** Triggers autoplay when the iframe loads */
22
+ autoplay?: boolean;
23
+
24
+ /** Prevents the video from being played */
25
+ disabled?: boolean;
26
+
27
+ /** Full YouTube URL — required. Component will not render if invalid. */
28
+ id?: NysVideoElement["id"];
29
+
30
+ /** Title text for the thumbnail of the video */
31
+ titleText?: NysVideoElement["titleText"];
32
+
33
+ /** Full YouTube URL — required. Component will not render if invalid. */
34
+ videourl?: NysVideoElement["videourl"];
35
+
36
+ /** Largest size for the video player.
37
+ If not set, size is determined automatically by viewport width. */
38
+ size?: NysVideoElement["size"];
39
+
40
+ /** undefined */
41
+ loading?: NysVideoElement["loading"];
42
+
43
+ /** Time in seconds where playback begins. * */
44
+ starttime?: NysVideoElement["starttime"];
45
+
46
+ /** Custom thumbnail image path.
47
+ Falls back to YouTube's auto-generated thumbnail if not provided. */
48
+ thumbnail?: NysVideoElement["thumbnail"];
49
+
50
+ /** A space-separated list of the classes of the element. Classes allows CSS and JavaScript to select and access specific elements via the class selectors or functions like the method `Document.getElementsByClassName()`. */
51
+ className?: string;
52
+
53
+ /** Contains a space-separated list of the part names of the element that should be exposed on the host element. */
54
+ exportparts?: string;
55
+
56
+ /** Used for labels to link them with their inputs (using input id). */
57
+ htmlFor?: string;
58
+
59
+ /** Used to help React identify which items have changed, are added, or are removed within a list. */
60
+ key?: number | string;
61
+
62
+ /** Contains a space-separated list of the part names of the element. Part names allows CSS to select and style specific elements in a shadow tree via the ::part pseudo-element. */
63
+ part?: string;
64
+
65
+ /** A mutable ref object whose `.current` property is initialized to the passed argument (`initialValue`). The returned object will persist for the full lifetime of the component. */
66
+ ref?: any;
67
+
68
+ /** Allows developers to make HTML elements focusable, allow or prevent them from being sequentially focusable (usually with the `Tab` key, hence the name) and determine their relative ordering for sequential focus navigation. */
69
+ tabIndex?: number;
70
+ }
71
+
72
+ /**
73
+ *
74
+ * ---
75
+ *
76
+ */
77
+ export const NysVideo: React.ForwardRefExoticComponent<NysVideoProps>;
@@ -0,0 +1,40 @@
1
+ import React, { forwardRef } from "react";
2
+ import "../../dist/nysds.es.js";
3
+
4
+ export const NysVideo = forwardRef((props, forwardedRef) => {
5
+ const {
6
+ autoplay,
7
+ disabled,
8
+ id,
9
+ titleText,
10
+ videourl,
11
+ size,
12
+ loading,
13
+ starttime,
14
+ thumbnail,
15
+ ...filteredProps
16
+ } = props;
17
+
18
+ return React.createElement(
19
+ "nys-video",
20
+ {
21
+ ...filteredProps,
22
+ id: props.id,
23
+ titleText: props.titleText,
24
+ videourl: props.videourl,
25
+ size: props.size,
26
+ loading: props.loading,
27
+ starttime: props.starttime,
28
+ thumbnail: props.thumbnail,
29
+ class: props.className,
30
+ exportparts: props.exportparts,
31
+ for: props.htmlFor,
32
+ part: props.part,
33
+ tabindex: props.tabIndex,
34
+ autoplay: props.autoplay ? true : undefined,
35
+ disabled: props.disabled ? true : undefined,
36
+ style: { ...props.style },
37
+ },
38
+ props.children,
39
+ );
40
+ });
@@ -1,37 +1,38 @@
1
1
  export * from "./NysAccordion.js";
2
2
  export * from "./NysAccordionItem.js";
3
- export * from "./NysAvatar.js";
4
3
  export * from "./NysAlert.js";
5
- export * from "./NysBadge.js";
4
+ export * from "./NysAvatar.js";
6
5
  export * from "./NysBacktotop.js";
6
+ export * from "./NysBadge.js";
7
7
  export * from "./NysButton.js";
8
8
  export * from "./NysCheckbox.js";
9
9
  export * from "./NysCheckboxgroup.js";
10
+ export * from "./NysCombobox.js";
10
11
  export * from "./NysDatepicker.js";
11
12
  export * from "./NysDivider.js";
12
13
  export * from "./NysDropdownMenu.js";
13
14
  export * from "./NysDropdownMenuItem.js";
14
15
  export * from "./NysErrorMessage.js";
15
- export * from "./NysGlobalFooter.js";
16
16
  export * from "./NysFileinput.js";
17
17
  export * from "./NysFileItem.js";
18
+ export * from "./NysGlobalFooter.js";
18
19
  export * from "./NysGlobalHeader.js";
19
20
  export * from "./NysIcon.js";
20
21
  export * from "./NysLabel.js";
22
+ export * from "./NysModal.js";
21
23
  export * from "./NysPagination.js";
24
+ export * from "./NysRadiobutton.js";
25
+ export * from "./NysRadiogroup.js";
22
26
  export * from "./NysOption.js";
23
27
  export * from "./NysSelect.js";
24
28
  export * from "./NysSkipnav.js";
25
29
  export * from "./NysStep.js";
26
30
  export * from "./NysStepper.js";
27
- export * from "./NysModal.js";
28
31
  export * from "./NysTable.js";
29
32
  export * from "./NysTextarea.js";
30
- export * from "./NysRadiobutton.js";
31
- export * from "./NysRadiogroup.js";
32
- export * from "./NysCombobox.js";
33
- export * from "./NysToggle.js";
34
33
  export * from "./NysTextinput.js";
34
+ export * from "./NysToggle.js";
35
35
  export * from "./NysTooltip.js";
36
- export * from "./NysUnavHeader.js";
37
36
  export * from "./NysUnavFooter.js";
37
+ export * from "./NysUnavHeader.js";
38
+ export * from "./NysVideo.js";
@@ -1,37 +1,38 @@
1
1
  export * from "./NysAccordion.js";
2
2
  export * from "./NysAccordionItem.js";
3
- export * from "./NysAvatar.js";
4
3
  export * from "./NysAlert.js";
5
- export * from "./NysBadge.js";
4
+ export * from "./NysAvatar.js";
6
5
  export * from "./NysBacktotop.js";
6
+ export * from "./NysBadge.js";
7
7
  export * from "./NysButton.js";
8
8
  export * from "./NysCheckbox.js";
9
9
  export * from "./NysCheckboxgroup.js";
10
+ export * from "./NysCombobox.js";
10
11
  export * from "./NysDatepicker.js";
11
12
  export * from "./NysDivider.js";
12
13
  export * from "./NysDropdownMenu.js";
13
14
  export * from "./NysDropdownMenuItem.js";
14
15
  export * from "./NysErrorMessage.js";
15
- export * from "./NysGlobalFooter.js";
16
16
  export * from "./NysFileinput.js";
17
17
  export * from "./NysFileItem.js";
18
+ export * from "./NysGlobalFooter.js";
18
19
  export * from "./NysGlobalHeader.js";
19
20
  export * from "./NysIcon.js";
20
21
  export * from "./NysLabel.js";
22
+ export * from "./NysModal.js";
21
23
  export * from "./NysPagination.js";
24
+ export * from "./NysRadiobutton.js";
25
+ export * from "./NysRadiogroup.js";
22
26
  export * from "./NysOption.js";
23
27
  export * from "./NysSelect.js";
24
28
  export * from "./NysSkipnav.js";
25
29
  export * from "./NysStep.js";
26
30
  export * from "./NysStepper.js";
27
- export * from "./NysModal.js";
28
31
  export * from "./NysTable.js";
29
32
  export * from "./NysTextarea.js";
30
- export * from "./NysRadiobutton.js";
31
- export * from "./NysRadiogroup.js";
32
- export * from "./NysCombobox.js";
33
- export * from "./NysToggle.js";
34
33
  export * from "./NysTextinput.js";
34
+ export * from "./NysToggle.js";
35
35
  export * from "./NysTooltip.js";
36
- export * from "./NysUnavHeader.js";
37
36
  export * from "./NysUnavFooter.js";
37
+ export * from "./NysUnavHeader.js";
38
+ export * from "./NysVideo.js";
@@ -36,7 +36,5 @@ export function useEventListener(targetElement, eventName, eventHandler) {
36
36
  return () => {
37
37
  element.removeEventListener(eventName, listener);
38
38
  };
39
- // Only re-subscribe when the element or event name changes.
40
- // Handler changes are handled via the savedHandler ref above.
41
39
  }, [eventName, targetElement]);
42
40
  }