@daoyi/nmtl-ui 2.0.1-beta.134 → 2.0.1-beta.135

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 (62) hide show
  1. package/README.md +45 -45
  2. package/lib/components/{Autocomplete-0ea4a31c.js → Autocomplete-e40d7145.js} +4 -4
  3. package/lib/components/Autocomplete.js +4 -4
  4. package/lib/components/Avatar.js +1 -1
  5. package/lib/components/BackTop.js +2 -2
  6. package/lib/components/BarChart.js +1 -1
  7. package/lib/components/Breadcrumbs.js +20 -9
  8. package/lib/components/{Button-7bd5aa09.js → Button-8cf35bc0.js} +1 -1
  9. package/lib/components/Button.js +2 -2
  10. package/lib/components/Carousel.js +1 -1
  11. package/lib/components/CollapseContent.js +46 -4
  12. package/lib/components/{ContactModal-159de99c.js → ContactModal-19979528.js} +37 -24
  13. package/lib/components/ContactModal.js +8 -8
  14. package/lib/components/{Drawer-2328b5f7.js → Drawer-b770014f.js} +2 -2
  15. package/lib/components/Drawer.js +5 -5
  16. package/lib/components/Dropdown.js +1 -1
  17. package/lib/components/{Empty-c6a44967.js → Empty-48685dd0.js} +1 -1
  18. package/lib/components/Empty.js +2 -2
  19. package/lib/components/ExportButton.js +1 -1
  20. package/lib/components/{ExtraTools-2691c13e.js → ExtraTools-c46c1965.js} +3 -3
  21. package/lib/components/ExtraTools.js +3 -3
  22. package/lib/components/Filter.js +2 -2
  23. package/lib/components/Footer.js +8 -8
  24. package/lib/components/{ForwardLink-5fbd2705.js → ForwardLink-2905563c.js} +2 -2
  25. package/lib/components/ForwardLink.js +3 -3
  26. package/lib/components/Header.js +8 -8
  27. package/lib/components/Image.js +1 -1
  28. package/lib/components/Input.js +1 -1
  29. package/lib/components/InputMethod.js +186 -196
  30. package/lib/components/{KeywordSearch-db9c45d9.js → KeywordSearch-4e621ded.js} +5 -5
  31. package/lib/components/KeywordSearch.js +5 -5
  32. package/lib/components/KeywordTicker.js +3 -3
  33. package/lib/components/Keywords.js +5 -5
  34. package/lib/components/Loading.js +1 -1
  35. package/lib/components/MUITheme.js +2 -2
  36. package/lib/components/{Modal-e04532fa.js → Modal-b984f381.js} +3 -3
  37. package/lib/components/Modal.js +4 -4
  38. package/lib/components/{MoreButton-19055e07.js → MoreButton-0b5aaef3.js} +2 -2
  39. package/lib/components/MoreButton.js +2 -2
  40. package/lib/components/Pagination.js +2 -2
  41. package/lib/components/SNA.js +11 -11
  42. package/lib/components/{SegmentedControl-81f63afc.js → SegmentedControl-804da0a6.js} +1 -1
  43. package/lib/components/SegmentedControl.js +2 -2
  44. package/lib/components/{Select-89841c71.js → Select-979f7e73.js} +2 -2
  45. package/lib/components/Select.js +3 -3
  46. package/lib/components/{Spin-8f87eadc.js → Spin-07679812.js} +1 -1
  47. package/lib/components/Spin.js +2 -2
  48. package/lib/components/{Tooltip-6ebfa9c1.js → Tooltip-bbbaa9c7.js} +1 -1
  49. package/lib/components/Tooltip.js +2 -2
  50. package/lib/components/globalConfig.js +19 -4
  51. package/lib/utils/arrayMerge.js +20 -20
  52. package/lib/utils/convert2HtmlEntities.js +5 -1
  53. package/lib/utils/exportXlsx.js +1 -1
  54. package/lib/utils/index.d.ts +2 -0
  55. package/lib/utils/index.js +2 -0
  56. package/lib/utils/newWindowHint-db113a69.js +49 -0
  57. package/lib/utils/prepareTimelineData.js +78 -0
  58. package/lib/utils/syncTimelineA11y.js +53 -0
  59. package/package.json +1 -1
  60. /package/lib/components/{createSvgIcon-dc603596.js → createSvgIcon-370e163a.js} +0 -0
  61. /package/lib/components/{index-b76a85f4.js → index-c33afcb5.js} +0 -0
  62. /package/lib/components/{index-b47819f3.js → index-ff95f719.js} +0 -0
package/README.md CHANGED
@@ -1,45 +1,45 @@
1
- # react-storybook-jsx-starter
2
-
3
- This project based
4
-
5
- This project is bootstrapped with the following
6
- - [Create React App](https://github.com/facebook/create-react-app)
7
- - [Storybook/react v.6.3.5](https://storybook.js.org/)
8
- - [Rollup v.2.54.0](https://rollupjs.org/guide/en/)
9
- - [Airbnb esint config v.18.0.0](https://www.npmjs.com/package/eslint-config-airbnb)
10
-
11
- ## Getting Started
12
-
13
-
14
- ## Available Scripts
15
-
16
- In the project directory, you can run:
17
-
18
- ### `yarn start` and `yarn storybook`
19
-
20
- Runs storybook.<br>
21
- Open [http://localhost:6006](http://localhost:6006) to view it in the browser.
22
- The page will reload if you make component edits.
23
-
24
- ### `yarn create`
25
-
26
- Help you create component or util. It will automatic generate `folder`, `JSX`, `.store.jsx`.
27
-
28
- ### `yarn lint`
29
-
30
- Runs airbnb linting config.<br>
31
- Please refer to `.eslintrc` for more details in rules that are excluded/added from the initial Airbnb configuration, which can be found [here](https://www.npmjs.com/package/eslint-config-airbnb)
32
- Notice: If developer using visual code IDE, download `eslint` and `prettier` extensions to help you develop.
33
-
34
- ### `yarn build`
35
-
36
- Builds the component library using rollup.<br>
37
- This runs a set of defined configurations under `rollup.config.js` file.<br>
38
- Index.js & index.ts will automatic generated by `rollup.index.js` file.
39
-
40
-
41
- ### `yarn build-storybook`
42
-
43
- Builds static files for storybook site. This is so it can be deployed as the docs source for the component library.
44
-
45
-
1
+ # react-storybook-jsx-starter
2
+
3
+ This project based
4
+
5
+ This project is bootstrapped with the following
6
+ - [Create React App](https://github.com/facebook/create-react-app)
7
+ - [Storybook/react v.6.3.5](https://storybook.js.org/)
8
+ - [Rollup v.2.54.0](https://rollupjs.org/guide/en/)
9
+ - [Airbnb esint config v.18.0.0](https://www.npmjs.com/package/eslint-config-airbnb)
10
+
11
+ ## Getting Started
12
+
13
+
14
+ ## Available Scripts
15
+
16
+ In the project directory, you can run:
17
+
18
+ ### `yarn start` and `yarn storybook`
19
+
20
+ Runs storybook.<br>
21
+ Open [http://localhost:6006](http://localhost:6006) to view it in the browser.
22
+ The page will reload if you make component edits.
23
+
24
+ ### `yarn create`
25
+
26
+ Help you create component or util. It will automatic generate `folder`, `JSX`, `.store.jsx`.
27
+
28
+ ### `yarn lint`
29
+
30
+ Runs airbnb linting config.<br>
31
+ Please refer to `.eslintrc` for more details in rules that are excluded/added from the initial Airbnb configuration, which can be found [here](https://www.npmjs.com/package/eslint-config-airbnb)
32
+ Notice: If developer using visual code IDE, download `eslint` and `prettier` extensions to help you develop.
33
+
34
+ ### `yarn build`
35
+
36
+ Builds the component library using rollup.<br>
37
+ This runs a set of defined configurations under `rollup.config.js` file.<br>
38
+ Index.js & index.ts will automatic generated by `rollup.index.js` file.
39
+
40
+
41
+ ### `yarn build-storybook`
42
+
43
+ Builds static files for storybook site. This is so it can be deployed as the docs source for the component library.
44
+
45
+
@@ -1,19 +1,19 @@
1
1
  import { _ as _extends$1, a as _slicedToArray, b as _objectSpread2 } from './_rollupPluginBabelHelpers-a52356f6.js';
2
2
  import React__default, { useCallback, useState, useRef, useEffect } from 'react';
3
3
  import PropTypes from 'prop-types';
4
- import { c as classNames } from './index-b76a85f4.js';
4
+ import { c as classNames } from './index-c33afcb5.js';
5
5
  import { d as debounce_1 } from './debounce-127da66c.js';
6
6
  import { Autocomplete as Autocomplete$1 } from '@material-ui/lab';
7
7
  import { Chip, TextField, CircularProgress } from '@material-ui/core';
8
8
  import { Close, SearchOutlined } from '@material-ui/icons';
9
- import { r as requireCreateSvgIcon, i as interopRequireDefault, a as interopRequireWildcard } from './createSvgIcon-dc603596.js';
9
+ import { r as requireCreateSvgIcon, i as interopRequireDefault, a as interopRequireWildcard } from './createSvgIcon-370e163a.js';
10
10
  import { _ as _extends, m as merge, d as defaultTheme, c as compose, b as borders, a as display, f as flexbox, g as grid, p as positions, e as palette, h as boxShadow, s as sizing, i as spacing, t as typography } from './defaultTheme-c5dd0f64.js';
11
11
  import 'react-is';
12
12
  import { _ as _toConsumableArray } from './toConsumableArray-c268c112.js';
13
13
  import { styled as styled$1 } from '@material-ui/styles';
14
14
  import { getIntl } from './globalConfig';
15
15
  import { s as styleInject } from './style-inject.es-1f59c1d0.js';
16
- import { E as Empty } from './Empty-c6a44967.js';
16
+ import { E as Empty } from './Empty-48685dd0.js';
17
17
 
18
18
  var ArrowDropDown = {};
19
19
 
@@ -294,7 +294,7 @@ var Autocomplete = function Autocomplete(props) {
294
294
  var handleSearch = useRef(debounce_1(function (result) {
295
295
  return onSearch(result);
296
296
  }, 500)).current;
297
- /* WCAG 2.4.3 renderAfterDefaultValueChange 重繪會使焦點掉到 body(NVDA 改從頁面頂端讀起、
297
+ /* WCAG 2.4.3 renderAfterDefaultValueChange 重繪會使焦點掉到 body(NVDA 改從頁面頂端讀起、
298
298
  蓋掉 aria-live 播報)——unmount 前記錄焦點是否在元件內,remount 後還原 */
299
299
  var rootRef = useRef(null);
300
300
  var hadFocusRef = useRef(false);
@@ -1,15 +1,15 @@
1
- export { A as default } from './Autocomplete-0ea4a31c.js';
1
+ export { A as default } from './Autocomplete-e40d7145.js';
2
2
  import './_rollupPluginBabelHelpers-a52356f6.js';
3
3
  import 'react';
4
4
  import 'prop-types';
5
- import './index-b76a85f4.js';
5
+ import './index-c33afcb5.js';
6
6
  import './debounce-127da66c.js';
7
7
  import './isObjectLike-e111475d.js';
8
8
  import './_commonjsHelpers-70de2c37.js';
9
9
  import '@material-ui/lab';
10
10
  import '@material-ui/core';
11
11
  import '@material-ui/icons';
12
- import './createSvgIcon-dc603596.js';
12
+ import './createSvgIcon-370e163a.js';
13
13
  import './defaultTheme-c5dd0f64.js';
14
14
  import 'react-is';
15
15
  import '@material-ui/styles';
@@ -17,4 +17,4 @@ import 'react-dom';
17
17
  import './toConsumableArray-c268c112.js';
18
18
  import './globalConfig';
19
19
  import './style-inject.es-1f59c1d0.js';
20
- import './Empty-c6a44967.js';
20
+ import './Empty-48685dd0.js';
@@ -1,5 +1,5 @@
1
1
  import React__default from 'react';
2
- import { c as classNames } from './index-b76a85f4.js';
2
+ import { c as classNames } from './index-c33afcb5.js';
3
3
  import PropTypes from 'prop-types';
4
4
  import { Avatar as Avatar$1 } from '@material-ui/core';
5
5
  import { s as styleInject } from './style-inject.es-1f59c1d0.js';
@@ -1,10 +1,10 @@
1
1
  import { a as _slicedToArray } from './_rollupPluginBabelHelpers-a52356f6.js';
2
2
  import React__default, { useState, useRef, useEffect } from 'react';
3
3
  import PropTypes from 'prop-types';
4
- import { c as classNames } from './index-b76a85f4.js';
4
+ import { c as classNames } from './index-c33afcb5.js';
5
5
  import { d as debounce_1 } from './debounce-127da66c.js';
6
6
  import { Fade, NoSsr, Box } from '@material-ui/core';
7
- import { r as requireCreateSvgIcon, i as interopRequireDefault, a as interopRequireWildcard } from './createSvgIcon-dc603596.js';
7
+ import { r as requireCreateSvgIcon, i as interopRequireDefault, a as interopRequireWildcard } from './createSvgIcon-370e163a.js';
8
8
  import { getIntl } from './globalConfig';
9
9
  import { s as styleInject } from './style-inject.es-1f59c1d0.js';
10
10
  import './isObjectLike-e111475d.js';
@@ -1,5 +1,5 @@
1
1
  import React__default, { useEffect } from 'react';
2
- import { c as classNames } from './index-b76a85f4.js';
2
+ import { c as classNames } from './index-c33afcb5.js';
3
3
  import PropTypes from 'prop-types';
4
4
  import { g as constant$1, h as interpolateNumber, j as color, k as interpolateRgb, l as interpolateString, n as exponent, o as ordinal, p as initRange, r as map, u as slice$1, v as bisectRight, w as formatSpecifier, x as formatPrefix, y as format, s as select } from './transform-849a452c.js';
5
5
  import { s as styleInject } from './style-inject.es-1f59c1d0.js';
@@ -1,8 +1,9 @@
1
1
  import React__default from 'react';
2
- import { c as classNames } from './index-b76a85f4.js';
2
+ import { c as classNames } from './index-c33afcb5.js';
3
3
  import PropTypes from 'prop-types';
4
- import { NavLink } from 'react-router-dom';
4
+ import { Link } from 'react-router-dom';
5
5
  import { Typography, Breadcrumbs as Breadcrumbs$1 } from '@material-ui/core';
6
+ import { getIntl } from './globalConfig';
6
7
  import { s as styleInject } from './style-inject.es-1f59c1d0.js';
7
8
 
8
9
  var css_248z$1 = ".breadcrumbItem {\n display: flex;\n opacity: 0.8;\n transition: opacity 0.1s ease-in-out;\n}\n.breadcrumbItem:hover {\n opacity: 1;\n}\n.breadcrumbItem--last {\n opacity: 1;\n font-weight: 500 !important;\n}\n.breadcrumbItem__icon {\n display: flex;\n align-items: center;\n margin-right: 4px;\n}\n.breadcrumbItem__icon svg {\n font-size: 1.125rem;\n}";
@@ -14,12 +15,14 @@ const BreadcrumbItem = _ref => {
14
15
  icon,
15
16
  text,
16
17
  lastItem,
18
+ current,
17
19
  onClick
18
20
  } = _ref;
19
21
  return /*#__PURE__*/React__default.createElement(Typography, {
20
22
  color: "textPrimary",
21
23
  className: className,
22
- onClick: onClick
24
+ onClick: onClick,
25
+ "aria-current": current ? 'page' : undefined
23
26
  }, /*#__PURE__*/React__default.createElement("div", {
24
27
  className: classNames('breadcrumbItem', {
25
28
  'breadcrumbItem--last': lastItem
@@ -35,6 +38,7 @@ BreadcrumbItem.defaultProps = {
35
38
  icon: undefined,
36
39
  text: undefined,
37
40
  lastItem: undefined,
41
+ current: false,
38
42
  onClick: () => {}
39
43
  };
40
44
  BreadcrumbItem.propTypes = {
@@ -42,6 +46,8 @@ BreadcrumbItem.propTypes = {
42
46
  icon: PropTypes.node,
43
47
  text: PropTypes.string,
44
48
  lastItem: PropTypes.bool,
49
+ /** 目前所在頁(麵包屑最後一項):加 aria-current="page" */
50
+ current: PropTypes.bool,
45
51
  onClick: PropTypes.func
46
52
  };
47
53
 
@@ -53,8 +59,11 @@ var Breadcrumbs = function Breadcrumbs(_ref) {
53
59
  links = _ref.links,
54
60
  separator = _ref.separator;
55
61
  return /*#__PURE__*/React__default.createElement(Breadcrumbs$1, {
56
- className: classNames('breadcrumbs', className),
57
- "aria-label": "breadcrumb",
62
+ className: classNames('breadcrumbs', className)
63
+ /* nav 地標名稱依語系(原本中文頁也唸英文 breadcrumb) */,
64
+ "aria-label": getIntl().formatMessage({
65
+ id: 'aria.breadcrumbs'
66
+ }),
58
67
  separator: separator && separator.length > 0 ? separator : undefined
59
68
  }, Array.isArray(links) && links.length > 0 && links.map(function (_ref2, i) {
60
69
  var icon = _ref2.icon,
@@ -63,18 +72,20 @@ var Breadcrumbs = function Breadcrumbs(_ref) {
63
72
  onClick = _ref2.onClick;
64
73
  var lastLink = i === links.length - 1;
65
74
 
66
- /* 尾巴 */
75
+ /* 尾巴=目前所在頁:aria-current="page" 標在這裡(WCAG 4.1.2,數位部人工檢測 GN1410200E,2026-10-07) */
67
76
  if (lastLink) return /*#__PURE__*/React__default.createElement(BreadcrumbItem, {
68
77
  key: i.toString(),
69
78
  lastItem: true,
79
+ current: true,
70
80
  icon: icon,
71
81
  text: text,
72
82
  onClick: onClick
73
83
  });
74
84
 
75
- /* 頭 */
85
+ /* 頭、中間用 Link 而不是 NavLink:NavLink 沒加 exact 時,「首頁」的 /zh-tw/ 是所有網址的開頭,
86
+ 會被自動標成 aria-current="page"+active,讀屏誤報首頁為目前頁(GN1410200E) */
76
87
  if (i === 0) {
77
- return /*#__PURE__*/React__default.createElement(NavLink, {
88
+ return /*#__PURE__*/React__default.createElement(Link, {
78
89
  className: "breadcrumbs__link",
79
90
  key: i.toString(),
80
91
  to: href || '/',
@@ -86,7 +97,7 @@ var Breadcrumbs = function Breadcrumbs(_ref) {
86
97
  }
87
98
 
88
99
  /* 中間 */
89
- return href ? /*#__PURE__*/React__default.createElement(NavLink, {
100
+ return href ? /*#__PURE__*/React__default.createElement(Link, {
90
101
  className: "breadcrumbs__link",
91
102
  key: i.toString(),
92
103
  to: href,
@@ -1,7 +1,7 @@
1
1
  import { c as _objectWithoutProperties, _ as _extends } from './_rollupPluginBabelHelpers-a52356f6.js';
2
2
  import React__default from 'react';
3
3
  import PropTypes from 'prop-types';
4
- import { c as classNames } from './index-b76a85f4.js';
4
+ import { c as classNames } from './index-c33afcb5.js';
5
5
  import { Button as Button$1, CircularProgress } from '@material-ui/core';
6
6
  import { s as styleInject } from './style-inject.es-1f59c1d0.js';
7
7
 
@@ -1,7 +1,7 @@
1
- export { B as default } from './Button-7bd5aa09.js';
1
+ export { B as default } from './Button-8cf35bc0.js';
2
2
  import './_rollupPluginBabelHelpers-a52356f6.js';
3
3
  import 'react';
4
4
  import 'prop-types';
5
- import './index-b76a85f4.js';
5
+ import './index-c33afcb5.js';
6
6
  import '@material-ui/core';
7
7
  import './style-inject.es-1f59c1d0.js';
@@ -1,6 +1,6 @@
1
1
  import { c as _objectWithoutProperties$1, b as _objectSpread2, _ as _extends$3 } from './_rollupPluginBabelHelpers-a52356f6.js';
2
2
  import React__default, { forwardRef, useRef, useImperativeHandle } from 'react';
3
- import { a as classnames, c as classNames } from './index-b76a85f4.js';
3
+ import { a as classnames, c as classNames } from './index-c33afcb5.js';
4
4
  import PropTypes from 'prop-types';
5
5
  import { c as commonjsGlobal, g as getAugmentedNamespace, a as getDefaultExportFromCjs } from './_commonjsHelpers-70de2c37.js';
6
6
  import { s as styleInject } from './style-inject.es-1f59c1d0.js';
@@ -1,12 +1,53 @@
1
1
  import { a as _slicedToArray } from './_rollupPluginBabelHelpers-a52356f6.js';
2
2
  import React__default, { useState, useRef, useEffect } from 'react';
3
- import { c as classNames } from './index-b76a85f4.js';
3
+ import { c as classNames } from './index-c33afcb5.js';
4
4
  import PropTypes from 'prop-types';
5
5
  import { Typography } from '@material-ui/core';
6
- import { M as MoreButton } from './MoreButton-19055e07.js';
6
+ import { M as MoreButton } from './MoreButton-0b5aaef3.js';
7
+ import { getIntl } from './globalConfig';
7
8
  import { s as styleInject } from './style-inject.es-1f59c1d0.js';
8
9
  import '@material-ui/icons';
9
- import './globalConfig';
10
+
11
+ /*
12
+ * 在 HTML 字串裡另開新視窗的連結文字後面補「(另開新視窗)」
13
+ * (數位部人工檢測 HM1240404E,2026-10-07:要直接寫在連結文字上,不能只放 title)。
14
+ * convert2HtmlEntities 與時間軸資料處理共用;不對外匯出。
15
+ */
16
+ const HINT_CLASS = 'newwindow-hint';
17
+ const hasHint = text => /另開新視窗|另开新窗口|new window/i.test(text);
18
+ const newWindowHintText = () => getIntl().formatMessage({
19
+ id: 'aria.newWindow'
20
+ });
21
+
22
+ /**
23
+ * @param {string} html
24
+ * @param {object} [options]
25
+ * @param {boolean} [options.treatMissingTargetAsBlank] 沒寫 target 的連結也當成另開新視窗
26
+ * (@daoyi/timeline 的 DOMPurify 會把它們強制改成 _blank)
27
+ * @param {string} [options.className] 提示 span 的 class
28
+ */
29
+ const addNewWindowHint = function (html) {
30
+ let {
31
+ treatMissingTargetAsBlank = false,
32
+ className = HINT_CLASS
33
+ } = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
34
+ if (typeof html !== 'string' || html.indexOf('<a') === -1 || typeof DOMParser === 'undefined') return html;
35
+ const doc = new DOMParser().parseFromString(`<body>${html}</body>`, 'text/html');
36
+ const hint = newWindowHintText();
37
+ let changed = false;
38
+ doc.body.querySelectorAll('a[href]').forEach(a => {
39
+ const target = (a.getAttribute('target') || (treatMissingTargetAsBlank ? '_blank' : '')).toLowerCase();
40
+ if (target !== '_blank') return;
41
+ if (!a.getAttribute('rel')) a.setAttribute('rel', 'noopener noreferrer');
42
+ if (hasHint(a.textContent)) return;
43
+ const span = doc.createElement('span');
44
+ span.className = className;
45
+ span.textContent = hint;
46
+ a.appendChild(span);
47
+ changed = true;
48
+ });
49
+ return changed ? doc.body.innerHTML : html;
50
+ };
10
51
 
11
52
  const HtmlToReactParser = require('html-to-react').Parser;
12
53
  const htmlToReactParser = new HtmlToReactParser();
@@ -47,7 +88,8 @@ const md = require('markdown-it')({
47
88
  // eslint-disable-next-line import/prefer-default-export
48
89
  const convert2HtmlEntities = text => {
49
90
  if (text === undefined) return '';
50
- return htmlToReactParser.parse(md.render(text));
91
+ /* 後台文稿裡 target="_blank" 的連結,連結文字補「(另開新視窗)」(HM1240404E,2026-10-07) */
92
+ return htmlToReactParser.parse(addNewWindowHint(md.render(text)));
51
93
  };
52
94
 
53
95
  /* eslint-disable react/no-danger */
@@ -8,15 +8,15 @@ import '@material-ui/styles';
8
8
  import { u as useTheme } from './useTheme-98b6cf17.js';
9
9
  import './withTheme-3486f38b.js';
10
10
  import axios from 'axios';
11
- import { M as Modal } from './Modal-e04532fa.js';
11
+ import { M as Modal } from './Modal-b984f381.js';
12
12
  import { c as commonjsGlobal, a as getDefaultExportFromCjs } from './_commonjsHelpers-70de2c37.js';
13
- import { c as classNames } from './index-b76a85f4.js';
13
+ import { c as classNames } from './index-c33afcb5.js';
14
14
  import { Input, IconButton, Button, Box, Typography, FormControl, RadioGroup, FormControlLabel, Radio, TextField, TextareaAutosize } from '@material-ui/core';
15
- import { S as Select } from './Select-89841c71.js';
15
+ import { S as Select } from './Select-979f7e73.js';
16
16
  import { VolumeUp } from '@material-ui/icons';
17
17
  import { getIntl } from './globalConfig';
18
18
  import { s as styleInject } from './style-inject.es-1f59c1d0.js';
19
- import { r as requireCreateSvgIcon, i as interopRequireDefault, a as interopRequireWildcard } from './createSvgIcon-dc603596.js';
19
+ import { r as requireCreateSvgIcon, i as interopRequireDefault, a as interopRequireWildcard } from './createSvgIcon-370e163a.js';
20
20
 
21
21
  var isArray$1 = Array.isArray;
22
22
  var keyList = Object.keys;
@@ -9984,7 +9984,7 @@ const VCode = _ref => {
9984
9984
  }, [visible]);
9985
9985
  const vcodeNumber = `${convert(data[0])}${convert(data[1])}${convert(data[2])}${convert(data[3])}`;
9986
9986
 
9987
- /* WCAG 1.1.1 驗證碼語音替代(tltc 認證模式):speechSynthesis 逐字報讀,
9987
+ /* WCAG 1.1.1 驗證碼語音替代(tltc 認證模式):speechSynthesis 逐字報讀,
9988
9988
  讓無法辨識圖片的使用者取得驗證碼內容 */
9989
9989
  const speakVerificationCode = () => {
9990
9990
  if ('speechSynthesis' in window) {
@@ -11677,15 +11677,23 @@ const FormItem = _ref => {
11677
11677
  } = getFormItemIds(name);
11678
11678
  /* 這些欄位型別會渲染帶 inputId 的 input,標題才能用 label htmlFor;其餘型別改以 aria-labelledby 關聯 */
11679
11679
  const hasInputId = ['input', 'textarea', 'datePicker', 'email', 'vcode'].includes(type);
11680
- /* WCAG 1.4.3 必填星號依主題深淺自動選色:formItem.scss 的 #b91c1c 只適用淺底 Modal,
11681
- 深色主題(如 ocean Paper #30353d)對比僅約 1.5:1(WAVE 實測被抓)→ 深色用 #ff8a80(約 5.4:1)。
11680
+ /* WCAG 1.4.3 必填星號依主題深淺自動選色:formItem.scss 的 #b91c1c 只適用淺底 Modal,
11681
+ 深色主題(如 ocean Paper #30353d)對比僅約 1.5:1(WAVE 實測被抓)→ 深色用 #ff8a80(約 5.4:1)。
11682
11682
  錯誤訊息同色,一併套用 */
11683
11683
  const theme = useTheme();
11684
11684
  const starStyle = theme && theme.palette && theme.palette.type === 'dark' ? {
11685
11685
  color: '#ff8a80'
11686
11686
  } : undefined;
11687
+ /* WCAG 3.3.2(數位部人工檢測 GN1330201E,2026-10-07):必填要直接寫成文字「(必填)」,
11688
+ 原本只有 aria-hidden 的星號,檢測認定讀屏無法正確提示。文字在 label 裡,會成為欄位名稱的一部分 */
11689
+ const requiredMark = required && /*#__PURE__*/React__default.createElement("span", {
11690
+ className: "formItem__title__star",
11691
+ style: starStyle
11692
+ }, formatMessage({
11693
+ id: 'common.form.required'
11694
+ }));
11687
11695
 
11688
- /* WCAG 3.3.1 欄位出錯時:aria-invalid,並以 aria-describedby 指向下方的錯誤訊息,
11696
+ /* WCAG 3.3.1 欄位出錯時:aria-invalid,並以 aria-describedby 指向下方的錯誤訊息,
11689
11697
  讀屏聚焦欄位就會唸出錯在哪裡(規範 04 §2)。沒有錯誤時兩者都不輸出 */
11690
11698
  const render = (field, _ref2) => {
11691
11699
  let {
@@ -11750,7 +11758,13 @@ const FormItem = _ref => {
11750
11758
  key: option.value
11751
11759
  }, /*#__PURE__*/React__default.createElement(FormControlLabel, {
11752
11760
  value: option.value,
11753
- control: /*#__PURE__*/React__default.createElement(Radio, null),
11761
+ htmlFor: `${inputId}-${option.value}`,
11762
+ control: /*#__PURE__*/React__default.createElement(Radio, {
11763
+ inputProps: {
11764
+ id: `${inputId}-${option.value}`,
11765
+ title: option.label
11766
+ }
11767
+ }),
11754
11768
  label: option.label
11755
11769
  }), option && option.desc && /*#__PURE__*/React__default.createElement(Typography, {
11756
11770
  variant: "caption",
@@ -11807,18 +11821,10 @@ const FormItem = _ref => {
11807
11821
  className: "formItem__title",
11808
11822
  id: labelId,
11809
11823
  htmlFor: inputId
11810
- }, label, required && /*#__PURE__*/React__default.createElement("div", {
11811
- className: "formItem__title__star",
11812
- style: starStyle,
11813
- "aria-hidden": "true"
11814
- }, "*")) : /*#__PURE__*/React__default.createElement("div", {
11824
+ }, label, requiredMark) : /*#__PURE__*/React__default.createElement("div", {
11815
11825
  className: "formItem__title",
11816
11826
  id: labelId
11817
- }, label, required && /*#__PURE__*/React__default.createElement("div", {
11818
- className: "formItem__title__star",
11819
- style: starStyle,
11820
- "aria-hidden": "true"
11821
- }, "*"))), hint && /*#__PURE__*/React__default.createElement(Box, {
11827
+ }, label, requiredMark)), hint && /*#__PURE__*/React__default.createElement(Box, {
11822
11828
  my: 1
11823
11829
  }, /*#__PURE__*/React__default.createElement(Typography, {
11824
11830
  variant: "body2"
@@ -11987,10 +11993,10 @@ const problemMail = _ref2 => {
11987
11993
  return body.join('<br />');
11988
11994
  };
11989
11995
 
11990
- var css_248z = "@charset \"UTF-8\";\n/* 送出失敗的錯誤摘要(WCAG 3.3.1,規範 04 §2);深色主題由 ContactModal 以 inline color 覆寫 */\n.contactModal__errorSummary {\n color: #b91c1c;\n border-left: 4px solid currentColor;\n padding: 0.5rem 0.75rem;\n margin-bottom: 1rem;\n /* 容器常駐 DOM(role=\"alert\" 才能可靠播報),沒有錯誤時不佔版面 */\n}\n.contactModal__errorSummary:empty {\n padding: 0;\n margin: 0;\n border: 0;\n}\n.contactModal__errorSummary__title {\n margin: 0 0 0.25rem;\n font-weight: bold;\n}\n.contactModal__errorSummary__list {\n margin: 0;\n padding-left: 1.25rem;\n}\n.contactModal__errorSummary__link {\n padding: 0;\n border: 0;\n background: none;\n color: inherit;\n font: inherit;\n text-align: left;\n text-decoration: underline;\n cursor: pointer;\n}";
11996
+ var css_248z = "@charset \"UTF-8\";\n/* 送出失敗的錯誤摘要(WCAG 3.3.1,規範 04 §2);深色主題由 ContactModal 以 inline color 覆寫 */\n.contactModal__errorSummary {\n color: #b91c1c;\n border-left: 4px solid currentColor;\n padding: 0.5rem 0.75rem;\n margin-bottom: 1rem;\n /* 容器常駐 DOM(role=\"alert\" 才能可靠播報),沒有錯誤時不佔版面 */\n}\n.contactModal__errorSummary:empty {\n padding: 0;\n margin: 0;\n border: 0;\n}\n.contactModal__errorSummary__title {\n margin: 0 0 0.25rem;\n font-weight: bold;\n}\n.contactModal__errorSummary__list {\n margin: 0;\n padding-left: 1.25rem;\n}\n.contactModal__errorSummary__link {\n padding: 0;\n border: 0;\n background: none;\n color: inherit;\n font: inherit;\n text-align: left;\n text-decoration: underline;\n cursor: pointer;\n}\n\n/* 必填欄位的說明(WCAG 3.3.2,GN1330201E) */\n.contactModal__requiredNote {\n margin: 0 0 1rem;\n}";
11991
11997
  styleInject(css_248z);
11992
11998
 
11993
- /* 錯誤摘要的「前往該欄位」:優先聚焦帶 inputId 的欄位;
11999
+ /* 錯誤摘要的「前往該欄位」:優先聚焦帶 inputId 的欄位;
11994
12000
  單選、下拉、上傳沒有該 id,改找欄位容器內第一個看得到、可聚焦的元素 */
11995
12001
  var focusFormItem = function focusFormItem(name) {
11996
12002
  var _getFormItemIds = getFormItemIds(name),
@@ -12175,8 +12181,8 @@ var ContactModal = function ContactModal(_ref) {
12175
12181
  setOpen(false);
12176
12182
  };
12177
12183
 
12178
- /* 送出:先取得驗證結果決定摘要內容,再交給 formik 送出。
12179
- formik 送出時會把所有欄位標為 touched,欄位下方的錯誤訊息才會出現;驗證通過才會真的寄信。
12184
+ /* 送出:先取得驗證結果決定摘要內容,再交給 formik 送出。
12185
+ formik 送出時會把所有欄位標為 touched,欄位下方的錯誤訊息才會出現;驗證通過才會真的寄信。
12180
12186
  (原本在 handleSubmit 之後同步讀取驗證結果,但 formik 2 的驗證是非同步的,第一次按送出時讀不到) */
12181
12187
  var handleSubmit = function handleSubmit() {
12182
12188
  formik.validateForm().then(function (errors) {
@@ -12244,7 +12250,14 @@ var ContactModal = function ContactModal(_ref) {
12244
12250
  return focusFormItem(name);
12245
12251
  }
12246
12252
  }, message));
12247
- })))), /*#__PURE__*/React__default.createElement(FormikProvider, {
12253
+ })))), template.some(function (_ref9) {
12254
+ var required = _ref9.required;
12255
+ return required;
12256
+ }) && /*#__PURE__*/React__default.createElement("p", {
12257
+ className: "contactModal__requiredNote"
12258
+ }, formatMessage({
12259
+ id: 'common.form.requiredNote'
12260
+ })), /*#__PURE__*/React__default.createElement(FormikProvider, {
12248
12261
  value: formik
12249
12262
  }, template.map(function (schema) {
12250
12263
  return /*#__PURE__*/React__default.createElement(FormItem, _extends$1({
@@ -1,4 +1,4 @@
1
- export { C as default } from './ContactModal-159de99c.js';
1
+ export { C as default } from './ContactModal-19979528.js';
2
2
  import './_rollupPluginBabelHelpers-a52356f6.js';
3
3
  import 'react';
4
4
  import 'prop-types';
@@ -9,16 +9,16 @@ import '@material-ui/styles';
9
9
  import './useTheme-98b6cf17.js';
10
10
  import './withTheme-3486f38b.js';
11
11
  import 'axios';
12
- import './Modal-e04532fa.js';
13
- import './index-b76a85f4.js';
12
+ import './Modal-b984f381.js';
13
+ import './index-c33afcb5.js';
14
14
  import '@material-ui/core';
15
15
  import '@material-ui/icons';
16
- import './Button-7bd5aa09.js';
16
+ import './Button-8cf35bc0.js';
17
17
  import './style-inject.es-1f59c1d0.js';
18
- import './Spin-8f87eadc.js';
18
+ import './Spin-07679812.js';
19
19
  import './globalConfig';
20
20
  import './_commonjsHelpers-70de2c37.js';
21
- import './Select-89841c71.js';
22
- import './Empty-c6a44967.js';
23
- import './createSvgIcon-dc603596.js';
21
+ import './Select-979f7e73.js';
22
+ import './Empty-48685dd0.js';
23
+ import './createSvgIcon-370e163a.js';
24
24
  import 'react-dom';
@@ -3,8 +3,8 @@ import React__default, { useState } from 'react';
3
3
  import PropTypes from 'prop-types';
4
4
  import { List, ListItem, ListItemIcon, ListItemText, IconButton, Drawer as Drawer$1, Divider } from '@material-ui/core';
5
5
  import { DehazeRounded, CloseRounded } from '@material-ui/icons';
6
- import { S as Select } from './Select-89841c71.js';
7
- import { S as SegmentedControl } from './SegmentedControl-81f63afc.js';
6
+ import { S as Select } from './Select-979f7e73.js';
7
+ import { S as SegmentedControl } from './SegmentedControl-804da0a6.js';
8
8
  import { useRouteMatch, NavLink } from 'react-router-dom';
9
9
  import { getIntl } from './globalConfig';
10
10
  import { s as styleInject } from './style-inject.es-1f59c1d0.js';
@@ -1,18 +1,18 @@
1
- export { D as default } from './Drawer-2328b5f7.js';
1
+ export { D as default } from './Drawer-b770014f.js';
2
2
  import './_rollupPluginBabelHelpers-a52356f6.js';
3
3
  import 'react';
4
4
  import 'prop-types';
5
5
  import '@material-ui/core';
6
6
  import '@material-ui/icons';
7
- import './Select-89841c71.js';
8
- import './index-b76a85f4.js';
7
+ import './Select-979f7e73.js';
8
+ import './index-c33afcb5.js';
9
9
  import './defaultTheme-c5dd0f64.js';
10
10
  import 'react-is';
11
11
  import '@material-ui/styles';
12
12
  import './useTheme-98b6cf17.js';
13
13
  import './withTheme-3486f38b.js';
14
- import './Empty-c6a44967.js';
14
+ import './Empty-48685dd0.js';
15
15
  import './style-inject.es-1f59c1d0.js';
16
16
  import './globalConfig';
17
- import './SegmentedControl-81f63afc.js';
17
+ import './SegmentedControl-804da0a6.js';
18
18
  import 'react-router-dom';
@@ -1,6 +1,6 @@
1
1
  import { a as _slicedToArray } from './_rollupPluginBabelHelpers-a52356f6.js';
2
2
  import React__default, { useRef, useState } from 'react';
3
- import { c as classNames } from './index-b76a85f4.js';
3
+ import { c as classNames } from './index-c33afcb5.js';
4
4
  import PropTypes from 'prop-types';
5
5
  import { Button, Menu, Divider, MenuItem, ListItemIcon, ListItemText } from '@material-ui/core';
6
6
  import { makeStyles } from '@material-ui/styles';
@@ -1,6 +1,6 @@
1
1
  import React__default from 'react';
2
2
  import PropTypes from 'prop-types';
3
- import { c as classNames } from './index-b76a85f4.js';
3
+ import { c as classNames } from './index-c33afcb5.js';
4
4
  import { s as styleInject } from './style-inject.es-1f59c1d0.js';
5
5
 
6
6
  var img = "data:image/svg+xml,%3csvg class='ant-empty-img-default' width='184' height='152' viewBox='0 0 184 152' xmlns='http://www.w3.org/2000/svg'%3e %3cg fill='none' fill-rule='evenodd'%3e %3cg transform='translate(24 31.67)'%3e %3cellipse fill='%23f5f5f5' fill-opacity='0.8' cx='67.797' cy='106.89' rx='67.797' ry='12.668'%3e%3c/ellipse%3e %3cpath fill='%23aeb8c2' d='M122.034 69.674L98.109 40.229c-1.148-1.386-2.826-2.225-4.593-2.225h-51.44c-1.766 0-3.444.839-4.592 2.225L13.56 69.674v15.383h108.475V69.674z'%3e%3c/path%3e %3cpath fill='url(%23linearGradient-1)' d='M101.537 86.214L80.63 61.102c-1.001-1.207-2.507-1.867-4.048-1.867H31.724c-1.54 0-3.047.66-4.048 1.867L6.769 86.214v13.792h94.768V86.214z' transform='translate(13.56)'%3e%3c/path%3e %3cpath fill='%23f5f5f7' d='M33.83 0h67.933a4 4 0 0 1 4 4v93.344a4 4 0 0 1-4 4H33.83a4 4 0 0 1-4-4V4a4 4 0 0 1 4-4z'%3e%3c/path%3e %3cpath fill='%23dce0e6' d='M42.678 9.953h50.237a2 2 0 0 1 2 2V36.91a2 2 0 0 1-2 2H42.678a2 2 0 0 1-2-2V11.953a2 2 0 0 1 2-2zM42.94 49.767h49.713a2.262 2.262 0 1 1 0 4.524H42.94a2.262 2.262 0 0 1 0-4.524zM42.94 61.53h49.713a2.262 2.262 0 1 1 0 4.525H42.94a2.262 2.262 0 0 1 0-4.525zM121.813 105.032c-.775 3.071-3.497 5.36-6.735 5.36H20.515c-3.238 0-5.96-2.29-6.734-5.36a7.309 7.309 0 0 1-.222-1.79V69.675h26.318c2.907 0 5.25 2.448 5.25 5.42v.04c0 2.971 2.37 5.37 5.277 5.37h34.785c2.907 0 5.277-2.421 5.277-5.393V75.1c0-2.972 2.343-5.426 5.25-5.426h26.318v33.569c0 .617-.077 1.216-.221 1.789z'%3e%3c/path%3e %3c/g%3e %3cpath fill='%23dce0e6' d='M149.121 33.292l-6.83 2.65a1 1 0 0 1-1.317-1.23l1.937-6.207c-2.589-2.944-4.109-6.534-4.109-10.408C138.802 8.102 148.92 0 161.402 0 173.881 0 184 8.102 184 18.097c0 9.995-10.118 18.097-22.599 18.097-4.528 0-8.744-1.066-12.28-2.902z'%3e%3c/path%3e %3cg fill='white' transform='translate(149.65 15.383)'%3e %3cellipse cx='20.654' cy='3.167' rx='2.849' ry='2.815'%3e%3c/ellipse%3e %3cpath d='M5.698 5.63H0L2.898.704zM9.259.704h4.985V5.63H9.259z'%3e%3c/path%3e %3c/g%3e %3c/g%3e%3c/svg%3e";
@@ -1,5 +1,5 @@
1
- export { E as default } from './Empty-c6a44967.js';
1
+ export { E as default } from './Empty-48685dd0.js';
2
2
  import 'react';
3
3
  import 'prop-types';
4
- import './index-b76a85f4.js';
4
+ import './index-c33afcb5.js';
5
5
  import './style-inject.es-1f59c1d0.js';
@@ -1,7 +1,7 @@
1
1
  import { a as _slicedToArray } from './_rollupPluginBabelHelpers-a52356f6.js';
2
2
  import React__default, { useState } from 'react';
3
3
  import PropTypes from 'prop-types';
4
- import { c as classNames } from './index-b76a85f4.js';
4
+ import { c as classNames } from './index-c33afcb5.js';
5
5
  import { ExitToApp } from '@material-ui/icons';
6
6
  import { Dialog, DialogContent, DialogContentText, DialogActions, Button } from '@material-ui/core';
7
7
  import { f as fileDownload, j as jsonTxt, a as jsonExcel } from './dataExport-a9e3fae1.js';
@@ -1,11 +1,11 @@
1
1
  import { _ as _extends } from './_rollupPluginBabelHelpers-a52356f6.js';
2
2
  import * as React from 'react';
3
3
  import React__default, { Component, forwardRef, useState, useRef, useEffect } from 'react';
4
- import { c as classNames } from './index-b76a85f4.js';
4
+ import { c as classNames } from './index-c33afcb5.js';
5
5
  import PropTypes from 'prop-types';
6
6
  import { a as getDefaultExportFromCjs } from './_commonjsHelpers-70de2c37.js';
7
7
  import { Menu, MenuItem, useMediaQuery, IconButton } from '@material-ui/core';
8
- import { T as Tooltip } from './Tooltip-6ebfa9c1.js';
8
+ import { T as Tooltip } from './Tooltip-bbbaa9c7.js';
9
9
  import { s as snaToExcel, f as fileDownload$1, a as jsonExcel } from './dataExport-a9e3fae1.js';
10
10
  import { getIntl } from './globalConfig';
11
11
  import { s as styleInject } from './style-inject.es-1f59c1d0.js';
@@ -2888,7 +2888,7 @@ const worksSlider = data => (data || []).map(_ref6 => {
2888
2888
  };
2889
2889
  });
2890
2890
 
2891
- /* \u532F\u51FA\u6A94\u540D\u7684\u65E5\u671F\u5F8C\u7DB4\uFF08YYYY-MM-DD\uFF09\uFF0C
2891
+ /* \u532F\u51FA\u6A94\u540D\u7684\u65E5\u671F\u5F8C\u7DB4\uFF08YYYY-MM-DD\uFF09\uFF0C
2892
2892
  \u8207 DownloadMenu \u4E0B\u8F09\u5716\u7247\u5171\u7528 */
2893
2893
  const exportDateSuffix = () => {
2894
2894
  const now = new Date();