@daoyi/nmtl-ui 2.0.1-beta.97 → 2.0.1-beta.99

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.
@@ -244,6 +244,7 @@ var Autocomplete = function Autocomplete(props) {
244
244
  onFocus = props.onFocus,
245
245
  onBlur = props.onBlur,
246
246
  onEnter = props.onEnter,
247
+ _onKeyDown = props.onKeyDown,
247
248
  arrowIcon = props.arrowIcon;
248
249
  var _useState = useState(true),
249
250
  _useState2 = _slicedToArray(_useState, 2),
@@ -351,6 +352,7 @@ var Autocomplete = function Autocomplete(props) {
351
352
  if (result && typeof result === 'string' && reason === 'input') setCurrentResult(result);
352
353
  },
353
354
  onKeyDown: function onKeyDown(event) {
355
+ _onKeyDown(event);
354
356
  switch (event.key) {
355
357
  case 'ArrowDown':
356
358
  case 'ArrowUp':
@@ -413,6 +415,7 @@ Autocomplete.defaultProps = {
413
415
  onSearch: function onSearch() {},
414
416
  onFocus: function onFocus() {},
415
417
  onBlur: function onBlur() {},
418
+ onKeyDown: function onKeyDown() {},
416
419
  onEnter: function onEnter() {},
417
420
  arrowIcon: false,
418
421
  ariaLabel: undefined
@@ -454,6 +457,8 @@ Autocomplete.propTypes = {
454
457
  onFocus: PropTypes.func,
455
458
  /** Input離開時的callback */
456
459
  onBlur: PropTypes.func,
460
+ /** 鍵盤按下任意鍵的callback(早於內部處理) */
461
+ onKeyDown: PropTypes.func,
457
462
  /** 鍵盤輸入Enter的callback */
458
463
  onEnter: PropTypes.func,
459
464
  /** 是否顯示arrow icon */
@@ -1,4 +1,4 @@
1
- export { A as default } from './Autocomplete-5d6f1df8.js';
1
+ export { A as default } from './Autocomplete-9e392b0c.js';
2
2
  import './_rollupPluginBabelHelpers-a52356f6.js';
3
3
  import 'react';
4
4
  import 'prop-types';
@@ -3,9 +3,10 @@ import React__default, { useState, useRef, useEffect } from 'react';
3
3
  import { c as classNames } from './index-b76a85f4.js';
4
4
  import PropTypes from 'prop-types';
5
5
  import { Typography } from '@material-ui/core';
6
- import { M as MoreButton } from './MoreButton-44d3b4fe.js';
6
+ import { M as MoreButton } from './MoreButton-692584cd.js';
7
7
  import { s as styleInject } from './style-inject.es-1f59c1d0.js';
8
8
  import '@material-ui/icons';
9
+ import './globalConfig';
9
10
 
10
11
  const HtmlToReactParser = require('html-to-react').Parser;
11
12
  const htmlToReactParser = new HtmlToReactParser();
@@ -6,8 +6,14 @@ import axios from 'axios';
6
6
  import { M as Modal } from './Modal-777fe87d.js';
7
7
  import { c as commonjsGlobal, a as getDefaultExportFromCjs } from './_commonjsHelpers-70de2c37.js';
8
8
  import { c as classNames } from './index-b76a85f4.js';
9
- import { Input, Button, Box, Typography, FormControl, RadioGroup, FormControlLabel, Radio, TextField, TextareaAutosize } from '@material-ui/core';
10
- import { S as Select } from './Select-ac580a1f.js';
9
+ import { Input, IconButton, Button, Box, Typography, FormControl, RadioGroup, FormControlLabel, Radio, TextField, TextareaAutosize } from '@material-ui/core';
10
+ import './defaultTheme-ed7746fe.js';
11
+ import 'react-is';
12
+ import '@material-ui/styles';
13
+ import { u as useTheme } from './useTheme-d16d02d9.js';
14
+ import './withTheme-2d778133.js';
15
+ import { S as Select } from './Select-e0790135.js';
16
+ import { VolumeUp } from '@material-ui/icons';
11
17
  import { getIntl } from './globalConfig';
12
18
  import { s as styleInject } from './style-inject.es-1f59c1d0.js';
13
19
  import { r as requireCreateSvgIcon, i as interopRequireDefault, a as interopRequireWildcard } from './createSvgIcon-e3803ee1.js';
@@ -10005,6 +10011,7 @@ const VCode = _ref => {
10005
10011
  required
10006
10012
  } = _ref;
10007
10013
  const [codeConfig, setCodeConfig] = useState(getConfig());
10014
+ const [liveMessage, setLiveMessage] = useState('');
10008
10015
  const {
10009
10016
  data,
10010
10017
  rotate,
@@ -10014,14 +10021,55 @@ const VCode = _ref => {
10014
10021
  const refresh = () => {
10015
10022
  canvas();
10016
10023
  setCodeConfig(getConfig());
10024
+ /* WCAG 4.1.3 刷新後播報(tltc 認證模式) */
10025
+ setLiveMessage(getIntl().formatMessage({
10026
+ id: 'aria.vcode.refreshed'
10027
+ }));
10028
+ setTimeout(() => setLiveMessage(''), 3000);
10017
10029
  };
10018
10030
  useEffect(() => {
10019
10031
  refresh();
10020
10032
  }, [visible]);
10021
10033
  const vcodeNumber = `${convert(data[0])}${convert(data[1])}${convert(data[2])}${convert(data[3])}`;
10034
+
10035
+ /* WCAG 1.1.1 驗證碼語音替代(tltc 認證模式):speechSynthesis 逐字報讀,
10036
+ 讓無法辨識圖片的使用者取得驗證碼內容 */
10037
+ const speakVerificationCode = () => {
10038
+ if ('speechSynthesis' in window) {
10039
+ window.speechSynthesis.cancel();
10040
+ const characters = vcodeNumber.split('');
10041
+ let currentIndex = 0;
10042
+ const speakNext = () => {
10043
+ if (currentIndex < characters.length) {
10044
+ const utterance = new SpeechSynthesisUtterance(characters[currentIndex]);
10045
+ utterance.rate = 0.7;
10046
+ utterance.onend = () => {
10047
+ currentIndex += 1;
10048
+ setTimeout(speakNext, 300);
10049
+ };
10050
+ window.speechSynthesis.speak(utterance);
10051
+ }
10052
+ };
10053
+ const introUtterance = new SpeechSynthesisUtterance(getIntl().formatMessage({
10054
+ id: 'aria.vcode.audioIntro'
10055
+ }));
10056
+ introUtterance.onend = () => setTimeout(speakNext, 500);
10057
+ window.speechSynthesis.speak(introUtterance);
10058
+ } else {
10059
+ setLiveMessage(getIntl().formatMessage({
10060
+ id: 'aria.vcode.audioUnsupported'
10061
+ }));
10062
+ setTimeout(() => setLiveMessage(''), 3000);
10063
+ }
10064
+ };
10022
10065
  return /*#__PURE__*/React__default.createElement("div", {
10023
10066
  className: "vcode"
10024
- }, /*#__PURE__*/React__default.createElement(Input, {
10067
+ }, /*#__PURE__*/React__default.createElement("div", {
10068
+ "aria-live": "polite",
10069
+ "aria-atomic": "true",
10070
+ role: "status",
10071
+ className: "visually-hidden"
10072
+ }, liveMessage), /*#__PURE__*/React__default.createElement(Input, {
10025
10073
  inputProps: {
10026
10074
  id: inputId,
10027
10075
  'aria-required': required || undefined
@@ -10032,7 +10080,18 @@ const VCode = _ref => {
10032
10080
  onChange: e => onChange(e.target.value.toUpperCase() === vcodeNumber.toUpperCase())
10033
10081
  }), /*#__PURE__*/React__default.createElement("div", {
10034
10082
  className: "vcode__box"
10035
- }, /*#__PURE__*/React__default.createElement("div", {
10083
+ }, /*#__PURE__*/React__default.createElement(IconButton, {
10084
+ className: "vcode__audio",
10085
+ "aria-label": getIntl().formatMessage({
10086
+ id: 'aria.vcode.audioPlay'
10087
+ }),
10088
+ title: getIntl().formatMessage({
10089
+ id: 'aria.vcode.audioPlay'
10090
+ }),
10091
+ onClick: speakVerificationCode
10092
+ }, /*#__PURE__*/React__default.createElement(VolumeUp, {
10093
+ "aria-hidden": "true"
10094
+ })), /*#__PURE__*/React__default.createElement("div", {
10036
10095
  className: "vcode__image",
10037
10096
  role: "img",
10038
10097
  "aria-label": getIntl().formatMessage({
@@ -11624,6 +11683,12 @@ const FormItem = _ref => {
11624
11683
  };
11625
11684
  /* 這些欄位型別會渲染帶 inputId 的 input,標題才能用 label htmlFor;其餘型別改以 aria-labelledby 關聯 */
11626
11685
  const hasInputId = ['input', 'textarea', 'datePicker', 'email', 'vcode'].includes(type);
11686
+ /* WCAG 1.4.3 必填星號依主題深淺自動選色:formItem.scss 的 #b91c1c 只適用淺底 Modal,
11687
+ 深色主題(如 ocean Paper #30353d)對比僅約 1.5:1(WAVE 實測被抓)→ 深色用 #ff8a80(約 5.4:1) */
11688
+ const theme = useTheme();
11689
+ const starStyle = theme && theme.palette && theme.palette.type === 'dark' ? {
11690
+ color: '#ff8a80'
11691
+ } : undefined;
11627
11692
  const render = field => {
11628
11693
  let component;
11629
11694
  switch (type) {
@@ -11721,12 +11786,14 @@ const FormItem = _ref => {
11721
11786
  htmlFor: inputId
11722
11787
  }, label, required && /*#__PURE__*/React__default.createElement("div", {
11723
11788
  className: "formItem__title__star",
11789
+ style: starStyle,
11724
11790
  "aria-hidden": "true"
11725
11791
  }, "*")) : /*#__PURE__*/React__default.createElement("div", {
11726
11792
  className: "formItem__title",
11727
11793
  id: labelId
11728
11794
  }, label, required && /*#__PURE__*/React__default.createElement("div", {
11729
11795
  className: "formItem__title__star",
11796
+ style: starStyle,
11730
11797
  "aria-hidden": "true"
11731
11798
  }, "*"))), hint && /*#__PURE__*/React__default.createElement(Box, {
11732
11799
  my: 1
@@ -1,4 +1,4 @@
1
- export { C as default } from './ContactModal-7427edd0.js';
1
+ export { C as default } from './ContactModal-90b95c63.js';
2
2
  import './_rollupPluginBabelHelpers-a52356f6.js';
3
3
  import 'react';
4
4
  import 'prop-types';
@@ -14,9 +14,11 @@ import './style-inject.es-1f59c1d0.js';
14
14
  import './Spin-8dc60bfe.js';
15
15
  import './globalConfig';
16
16
  import './_commonjsHelpers-70de2c37.js';
17
- import './Select-ac580a1f.js';
18
- import './Empty-bf77164f.js';
19
- import './createSvgIcon-e3803ee1.js';
20
17
  import './defaultTheme-ed7746fe.js';
21
18
  import '@material-ui/styles';
19
+ import './useTheme-d16d02d9.js';
20
+ import './withTheme-2d778133.js';
21
+ import './Select-e0790135.js';
22
+ import './Empty-bf77164f.js';
23
+ import './createSvgIcon-e3803ee1.js';
22
24
  import 'react-dom';
@@ -3,7 +3,7 @@ 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 } from '@material-ui/icons';
6
- import { S as Select } from './Select-ac580a1f.js';
6
+ import { S as Select } from './Select-e0790135.js';
7
7
  import { useHistory, useRouteMatch } from 'react-router-dom';
8
8
  import { getIntl } from './globalConfig';
9
9
  import { s as styleInject } from './style-inject.es-1f59c1d0.js';
@@ -1,11 +1,16 @@
1
- export { D as default } from './Drawer-41d3a91f.js';
1
+ export { D as default } from './Drawer-2cbcec04.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-ac580a1f.js';
7
+ import './Select-e0790135.js';
8
8
  import './index-b76a85f4.js';
9
+ import './defaultTheme-ed7746fe.js';
10
+ import 'react-is';
11
+ import '@material-ui/styles';
12
+ import './useTheme-d16d02d9.js';
13
+ import './withTheme-2d778133.js';
9
14
  import './Empty-bf77164f.js';
10
15
  import './style-inject.es-1f59c1d0.js';
11
16
  import 'react-router-dom';
@@ -3143,7 +3143,7 @@ const ResetMobileIcon = _ref => {
3143
3143
  })));
3144
3144
  };
3145
3145
 
3146
- var css_248z = ".extraTools {\n width: 100%;\n display: inline-flex;\n justify-content: flex-end;\n align-items: center;\n gap: 1rem;\n padding: 0px 20px;\n padding-top: 12px;\n}\n.extraTools__share button {\n display: flex;\n justify-content: center;\n align-items: center;\n}\n.extraTools__download {\n cursor: pointer;\n}\n.extraTools__download-icon {\n display: flex;\n justify-content: center;\n align-items: center;\n}\n.extraTools__fullscreenBtn {\n cursor: pointer;\n padding-top: 0;\n}\n.extraTools__fullscreenBtn-icon {\n display: flex;\n justify-content: center;\n align-items: center;\n}\n.extraTools__fontsize {\n display: flex;\n justify-content: center;\n align-items: center;\n}\n.extraTools .font-size-changer,\n.extraTools .font-size-changer-buttons,\n.extraTools .font-size-up,\n.extraTools .font-size-down,\n.extraTools .tooltip {\n display: flex;\n justify-content: center;\n align-items: center;\n}\n.extraTools .font-size-up {\n width: 32px !important;\n cursor: pointer;\n margin-right: 16px !important;\n}\n.extraTools .font-size-down {\n cursor: pointer;\n width: 32px !important;\n}\n.extraTools .font-size-up,\n.extraTools .font-size-down {\n height: 32px;\n line-height: 32px !important;\n}\n.extraTools .fullscreenExit {\n text-align: right;\n cursor: pointer;\n border: 0;\n}\n.extraTools #download-menu .MuiMenuItem-root {\n color: #4e3a16;\n width: auto;\n overflow: hidden;\n font-size: 1rem;\n box-sizing: border-box;\n min-height: 48px;\n font-weight: 400;\n line-height: 1;\n padding-top: 1rem;\n white-space: initial;\n border-bottom: 0;\n letter-spacing: 0.00938em;\n padding-bottom: 1rem;\n}";
3146
+ var css_248z = ".extraTools {\n width: 100%;\n display: inline-flex;\n justify-content: flex-end;\n align-items: center;\n gap: 1rem;\n padding: 0px 20px;\n padding-top: 12px;\n padding-bottom: 6px;\n}\n.extraTools__share button {\n display: flex;\n justify-content: center;\n align-items: center;\n}\n.extraTools__download {\n cursor: pointer;\n}\n.extraTools__download-icon {\n display: flex;\n justify-content: center;\n align-items: center;\n}\n.extraTools__fullscreenBtn {\n cursor: pointer;\n padding-top: 0;\n}\n.extraTools__fullscreenBtn-icon {\n display: flex;\n justify-content: center;\n align-items: center;\n}\n.extraTools__fontsize {\n display: flex;\n justify-content: center;\n align-items: center;\n}\n.extraTools .font-size-changer,\n.extraTools .font-size-changer-buttons,\n.extraTools .font-size-up,\n.extraTools .font-size-down,\n.extraTools .tooltip {\n display: flex;\n justify-content: center;\n align-items: center;\n}\n.extraTools .font-size-up {\n width: 32px !important;\n cursor: pointer;\n margin-right: 16px !important;\n}\n.extraTools .font-size-down {\n cursor: pointer;\n width: 32px !important;\n}\n.extraTools .font-size-up,\n.extraTools .font-size-down {\n height: 32px;\n line-height: 32px !important;\n}\n.extraTools .font-size-changer .font-size-changer-buttons > div {\n float: none;\n height: 32px;\n line-height: 32px !important;\n align-self: center;\n margin-top: 0;\n margin-bottom: 0;\n}\n.extraTools .fullscreenExit {\n text-align: right;\n cursor: pointer;\n border: 0;\n}\n.extraTools #download-menu .MuiMenuItem-root {\n color: #4e3a16;\n width: auto;\n overflow: hidden;\n font-size: 1rem;\n box-sizing: border-box;\n min-height: 48px;\n font-weight: 400;\n line-height: 1;\n padding-top: 1rem;\n white-space: initial;\n border-bottom: 0;\n letter-spacing: 0.00938em;\n padding-bottom: 1rem;\n}";
3147
3147
  styleInject(css_248z);
3148
3148
 
3149
3149
  /* eslint-disable prefer-destructuring */
@@ -1,4 +1,4 @@
1
- export { E as default } from './ExtraTools-8d2ef84d.js';
1
+ export { E as default } from './ExtraTools-55f66039.js';
2
2
  import './_rollupPluginBabelHelpers-a52356f6.js';
3
3
  import 'react';
4
4
  import './index-b76a85f4.js';
@@ -3,8 +3,9 @@ import React__default, { useState, useEffect } from 'react';
3
3
  import { c as classNames } from './index-b76a85f4.js';
4
4
  import PropTypes from 'prop-types';
5
5
  import axios from 'axios';
6
- import { C as ContactModal } from './ContactModal-7427edd0.js';
6
+ import { C as ContactModal } from './ContactModal-90b95c63.js';
7
7
  import { S as Spin } from './Spin-8dc60bfe.js';
8
+ import { getIntl } from './globalConfig';
8
9
  import { s as styleInject } from './style-inject.es-1f59c1d0.js';
9
10
  import './hoist-non-react-statics.cjs-3f408ad2.js';
10
11
  import 'react-is';
@@ -12,13 +13,14 @@ import './Modal-777fe87d.js';
12
13
  import '@material-ui/core';
13
14
  import '@material-ui/icons';
14
15
  import './Button-305b69a0.js';
15
- import './globalConfig';
16
16
  import './_commonjsHelpers-70de2c37.js';
17
- import './Select-ac580a1f.js';
18
- import './Empty-bf77164f.js';
19
- import './createSvgIcon-e3803ee1.js';
20
17
  import './defaultTheme-ed7746fe.js';
21
18
  import '@material-ui/styles';
19
+ import './useTheme-d16d02d9.js';
20
+ import './withTheme-2d778133.js';
21
+ import './Select-e0790135.js';
22
+ import './Empty-bf77164f.js';
23
+ import './createSvgIcon-e3803ee1.js';
22
24
  import 'react-dom';
23
25
 
24
26
  /* eslint-disable max-len */
@@ -128,13 +130,25 @@ var Footer = function Footer(props) {
128
130
  style: {
129
131
  background: color
130
132
  }
131
- }, /*#__PURE__*/React__default.createElement(NmtlLogo, {
132
- className: "footer__logo",
133
- color: primaryColor,
133
+ }, /*#__PURE__*/React__default.createElement("span", {
134
+ role: "link",
135
+ tabIndex: 0,
136
+ "aria-label": getIntl().formatMessage({
137
+ id: 'aria.footer.nmtlLogo'
138
+ }),
134
139
  onClick: function onClick() {
135
140
  return window.open('https://www.nmtl.gov.tw/');
141
+ },
142
+ onKeyDown: function onKeyDown(event) {
143
+ if (event.key === 'Enter') {
144
+ event.preventDefault();
145
+ window.open('https://www.nmtl.gov.tw/');
146
+ }
136
147
  }
137
- }), /*#__PURE__*/React__default.createElement("div", {
148
+ }, /*#__PURE__*/React__default.createElement(NmtlLogo, {
149
+ className: "footer__logo",
150
+ color: primaryColor
151
+ })), /*#__PURE__*/React__default.createElement("div", {
138
152
  className: "footer__content"
139
153
  }, counter && /*#__PURE__*/React__default.createElement("div", {
140
154
  className: "footer__content__item",
@@ -198,16 +212,23 @@ var Footer = function Footer(props) {
198
212
  key: i.toString()
199
213
  }, name.toUpperCase());
200
214
  }
201
- return /*#__PURE__*/React__default.createElement("a", {
202
- className: "footer__content__item__link",
203
- style: {
204
- color: primaryColor
205
- },
206
- href: url,
207
- key: i.toString(),
208
- target: "_blank",
209
- rel: "noopener noreferrer"
210
- }, name.toUpperCase());
215
+ return (
216
+ /*#__PURE__*/
217
+ /* WCAG 3.2.2 另開新視窗需預先提示(比照 ForwardLink 模式) */
218
+ React__default.createElement("a", {
219
+ className: "footer__content__item__link",
220
+ style: {
221
+ color: primaryColor
222
+ },
223
+ href: url,
224
+ key: i.toString(),
225
+ target: "_blank",
226
+ rel: "noopener noreferrer",
227
+ "aria-label": "".concat(name.toUpperCase()).concat(getIntl().formatMessage({
228
+ id: 'aria.newWindow'
229
+ }))
230
+ }, name.toUpperCase())
231
+ );
211
232
  }), /*#__PURE__*/React__default.createElement("div", {
212
233
  className: "footer__content__item__link",
213
234
  style: {
@@ -216,6 +237,11 @@ var Footer = function Footer(props) {
216
237
  role: "button",
217
238
  tabIndex: 0,
218
239
  "aria-haspopup": "dialog",
240
+ "aria-label": "".concat(formatMessage({
241
+ id: 'common.has.problem'
242
+ })).concat(getIntl().formatMessage({
243
+ id: 'aria.opensDialog'
244
+ })),
219
245
  onClick: function onClick() {
220
246
  return setContactModalOpen(true);
221
247
  },
@@ -6,15 +6,15 @@ import { d as debounce_1 } from './debounce-127da66c.js';
6
6
  import { useHistory, useRouteMatch, NavLink } from 'react-router-dom';
7
7
  import { Typography, IconButton } from '@material-ui/core';
8
8
  import { SearchOutlined } from '@material-ui/icons';
9
- import { K as KeywordSearch } from './KeywordSearch-33341dd3.js';
10
- import { S as Select } from './Select-ac580a1f.js';
11
- import { c as checkLanguageSupport, D as Drawer, d as defaultSupportLanguage } from './Drawer-41d3a91f.js';
9
+ import { K as KeywordSearch } from './KeywordSearch-d378ca7f.js';
10
+ import { S as Select } from './Select-e0790135.js';
11
+ import { c as checkLanguageSupport, D as Drawer, d as defaultSupportLanguage } from './Drawer-2cbcec04.js';
12
12
  import { getIntl } from './globalConfig';
13
13
  import { s as styleInject } from './style-inject.es-1f59c1d0.js';
14
14
  import './isObjectLike-e111475d.js';
15
15
  import './_commonjsHelpers-70de2c37.js';
16
16
  import 'axios';
17
- import './Autocomplete-5d6f1df8.js';
17
+ import './Autocomplete-9e392b0c.js';
18
18
  import '@material-ui/lab';
19
19
  import './createSvgIcon-e3803ee1.js';
20
20
  import './defaultTheme-ed7746fe.js';
@@ -23,6 +23,8 @@ import '@material-ui/styles';
23
23
  import 'react-dom';
24
24
  import './toConsumableArray-dbe8af76.js';
25
25
  import './Empty-bf77164f.js';
26
+ import './useTheme-d16d02d9.js';
27
+ import './withTheme-2d778133.js';
26
28
 
27
29
  var css_248z = "@charset \"UTF-8\";\n.header {\n display: flex;\n align-items: center;\n background: rgba(255, 255, 255, 0.6);\n background-color: rgba(255, 255, 255, 0.6);\n padding: 12px 36px !important;\n position: fixed;\n top: 0;\n z-index: 10;\n width: 100% !important;\n transition: top 0.3s ease-in-out;\n box-shadow: 0 2px 4px 0 rgba(0, 0, 0, 0.1);\n}\n.header__logo {\n display: flex;\n width: -moz-fit-content !important;\n width: fit-content !important;\n margin-right: 30px !important;\n cursor: pointer;\n}\n.header__logo__img {\n display: flex;\n align-items: center;\n}\n.header__logo__title {\n white-space: nowrap;\n margin-left: 1rem !important;\n font-size: 1.5rem !important;\n font-weight: 700 !important;\n font-family: \"Noto Sans TC\" !important;\n}\n.header__links {\n display: flex;\n justify-content: flex-end;\n padding-right: 14px;\n}\n.header__links a {\n text-decoration: none;\n}\n.header__links--full {\n flex: 1;\n}\n.header__links__item {\n color: rgba(0, 0, 0, 0.85);\n font-size: 1.125rem !important;\n font-weight: 500 !important;\n white-space: nowrap;\n padding: 6px 14px;\n font-family: \"Noto Sans TC\" !important;\n}\n.header__links__item--active .header__links__item {\n font-weight: 800 !important;\n background: transparent;\n border-radius: 45px;\n}\n.header__links__item:hover {\n font-weight: 800 !important;\n}\n.header__language {\n min-width: 100px !important;\n}\n.header__searchIcon {\n display: none !important;\n}\n@media screen and (max-width: 768px) {\n .header--smallUseSearchIcon .header__searchIcon {\n display: flex !important;\n margin-right: 10px !important;\n }\n .header--smallUseSearchIcon .keywordSearch {\n visibility: hidden;\n flex: 1;\n width: 0;\n }\n}\n.header--hide {\n top: -100px;\n}\n.header--focus .header__links {\n display: none;\n}\n.header .MuiTypography-root {\n width: 100%;\n display: flex;\n align-items: center;\n}\n.header .autocomplete {\n float: right;\n}\n.header .autocomplete .MuiAutocomplete-inputRoot[class*=MuiOutlinedInput-root] {\n padding: 1px 8px !important;\n}\n.header .keywordSearch {\n margin-right: 8px;\n}\n.header .keywordSearch--focus .autocomplete {\n width: 100% !important;\n}\n.header .keywordSearch--animation .autocomplete {\n width: 240px;\n transition: width 0.3s ease-in-out;\n}\n\n/* 避免寬度460以下炸版 */\n@media screen and (max-width: 460px) {\n .header .keywordSearch--animation .autocomplete {\n width: 100%;\n }\n}\n@media screen and (max-width: 768px) {\n .header {\n padding: 12px 15px !important;\n }\n .header__logo {\n margin-right: 16px !important;\n }\n .header__logo__title {\n display: none !important;\n }\n .header__links {\n display: none;\n }\n .header__links__item {\n font-size: 1rem !important;\n }\n .header__language {\n display: none !important;\n }\n .header--focus .header__logo {\n display: none !important;\n }\n\n .autocomplete__icon {\n display: none !important;\n }\n}";
28
30
  styleInject(css_248z);
@@ -122,10 +124,18 @@ var Header = function Header(props) {
122
124
  className: "header__links__item",
123
125
  color: typographyColor
124
126
  }, name);
125
- return path.indexOf('http') > -1 ? /*#__PURE__*/React__default.createElement("a", {
127
+ return path.indexOf('http') > -1 ?
128
+ /*#__PURE__*/
129
+ /* WCAG 3.2.2 外部連結(如文學好臺誌)另開新視窗需預先提示 */
130
+ React__default.createElement("a", {
126
131
  key: i.toString(),
127
132
  href: path,
128
- className: "header__links__item--active"
133
+ className: "header__links__item--active",
134
+ target: "_blank",
135
+ rel: "noopener noreferrer",
136
+ "aria-label": "".concat(name).concat(getIntl().formatMessage({
137
+ id: 'aria.newWindow'
138
+ }))
129
139
  }, label) : /*#__PURE__*/React__default.createElement(NavLink, {
130
140
  key: i.toString(),
131
141
  to: "".concat(url).concat(path),
@@ -4,7 +4,7 @@ import PropTypes from 'prop-types';
4
4
  import { c as classNames } from './index-b76a85f4.js';
5
5
  import axios from 'axios';
6
6
  import { s as styleInject } from './style-inject.es-1f59c1d0.js';
7
- import { A as Autocomplete } from './Autocomplete-5d6f1df8.js';
7
+ import { A as Autocomplete } from './Autocomplete-9e392b0c.js';
8
8
 
9
9
  var css_248z = ".keywordSearch {\n border-radius: 4px;\n width: 100%;\n margin-right: 14px;\n}\n.keywordSearch--animation .autocomplete {\n transition: max-width 0.3s ease-out;\n max-width: 240px;\n}\n.keywordSearch--focus {\n flex: 1;\n}\n.keywordSearch--focus .autocomplete {\n max-width: 100%;\n}\n.keywordSearch .MuiAutocomplete-hasPopupIcon.MuiAutocomplete-hasClearIcon .MuiAutocomplete-inputRoot[class*=MuiOutlinedInput-root] {\n border-radius: 10px;\n background-color: #ffffff66;\n}";
10
10
  styleInject(css_248z);
@@ -106,6 +106,13 @@ var KeywordSearch = function KeywordSearch(_ref) {
106
106
  },
107
107
  onBlur: function onBlur() {
108
108
  return setMenuOpen(false);
109
+ },
110
+ onKeyDown: function onKeyDown(event) {
111
+ /* WCAG 2.1.1:搜尋框聚焦時 header--focus 會 display:none 隱藏導覽連結,
112
+ 瀏覽器在 keydown 當下就決定 Tab 的下一個焦點目標——若等 blur 才收合,
113
+ 導覽連結永遠不在焦點順序中。改在 Tab 按下時同步收合(React 事件結尾
114
+ 同步 re-render,早於瀏覽器預設移焦),讓導覽連結恢復可聚焦。 */
115
+ if (event.key === 'Tab') setMenuOpen(false);
109
116
  }
110
117
  }));
111
118
  };
@@ -1,11 +1,11 @@
1
- export { K as default } from './KeywordSearch-33341dd3.js';
1
+ export { K as default } from './KeywordSearch-d378ca7f.js';
2
2
  import './_rollupPluginBabelHelpers-a52356f6.js';
3
3
  import 'react';
4
4
  import 'prop-types';
5
5
  import './index-b76a85f4.js';
6
6
  import 'axios';
7
7
  import './style-inject.es-1f59c1d0.js';
8
- import './Autocomplete-5d6f1df8.js';
8
+ import './Autocomplete-9e392b0c.js';
9
9
  import './debounce-127da66c.js';
10
10
  import './isObjectLike-e111475d.js';
11
11
  import './_commonjsHelpers-70de2c37.js';
@@ -3,13 +3,13 @@ import React__default, { useState, useRef, useEffect } from 'react';
3
3
  import PropTypes from 'prop-types';
4
4
  import { c as classNames } from './index-b76a85f4.js';
5
5
  import { F as ForwardLink } from './ForwardLink-83a7eea9.js';
6
+ import { getIntl } from './globalConfig';
6
7
  import { s as styleInject } from './style-inject.es-1f59c1d0.js';
7
8
  import './index-b47819f3.js';
8
9
  import 'react-router-dom';
9
10
  import '@material-ui/core';
10
- import './globalConfig';
11
11
 
12
- var css_248z = ".keywordTicker {\n width: 100%;\n display: flex;\n justify-content: flex-start;\n align-items: center;\n}\n.keywordTicker__track {\n display: flex;\n width: 100%;\n padding: 20px 0px;\n background-color: #ece8c0;\n overflow: hidden;\n margin-left: -80px;\n padding-left: 100px;\n z-index: 1;\n position: relative;\n}\n.keywordTicker__items {\n display: flex;\n justify-content: flex-start;\n align-items: center;\n flex-wrap: nowrap;\n position: relative;\n}\n.keywordTicker-item {\n width: auto;\n display: flex;\n justify-content: center;\n align-items: center;\n white-space: nowrap;\n cursor: pointer;\n}\n.keywordTicker-text {\n font-size: 1.5rem;\n z-index: 2;\n font-weight: bold;\n color: #825c0d;\n border-left: 2px solid #fff;\n padding: 0px 40px;\n}\n.keywordTicker__img {\n z-index: 2;\n position: relative;\n display: flex;\n}\n.keywordTicker__img img {\n height: 100%;\n max-height: 195px;\n image-rendering: -webkit-optimize-contrast;\n position: relative;\n}\n.keywordTicker--fake {\n position: absolute;\n opacity: 0;\n width: 100%;\n}\n\n@media only screen and (max-width: 768px) {\n .keywordTicker-text {\n font-size: 1.5rem;\n padding: 0px 15px;\n }\n .keywordTicker__img img {\n max-height: 104px;\n left: -60px;\n }\n .keywordTicker__track {\n padding: 10px 0px;\n margin-left: -100px;\n }\n}\n@media only screen and (max-width: 484px) {\n .keywordTicker-text {\n font-size: 14px;\n }\n}";
12
+ var css_248z = ".keywordTicker {\n width: 100%;\n display: flex;\n justify-content: flex-start;\n align-items: center;\n position: relative;\n}\n.keywordTicker__playToggle {\n position: absolute;\n top: 0;\n left: 0;\n z-index: 3;\n padding: 4px 12px;\n background: rgba(0, 0, 0, 0.75);\n color: #fff;\n border: 1px solid #fff;\n border-radius: 4px;\n font-size: 1rem;\n cursor: pointer;\n}\n.keywordTicker__track {\n display: flex;\n width: 100%;\n padding: 20px 0px;\n background-color: #ece8c0;\n overflow: hidden;\n margin-left: -80px;\n padding-left: 100px;\n z-index: 1;\n position: relative;\n}\n.keywordTicker__items {\n display: flex;\n justify-content: flex-start;\n align-items: center;\n flex-wrap: nowrap;\n position: relative;\n}\n.keywordTicker-item {\n width: auto;\n display: flex;\n justify-content: center;\n align-items: center;\n white-space: nowrap;\n cursor: pointer;\n}\n.keywordTicker-text {\n font-size: 1.5rem;\n z-index: 2;\n font-weight: bold;\n color: #825c0d;\n border-left: 2px solid #fff;\n padding: 0px 40px;\n}\n.keywordTicker__img {\n z-index: 2;\n position: relative;\n display: flex;\n}\n.keywordTicker__img img {\n height: 100%;\n max-height: 195px;\n image-rendering: -webkit-optimize-contrast;\n position: relative;\n}\n.keywordTicker--fake {\n position: absolute;\n opacity: 0;\n width: 100%;\n}\n\n@media only screen and (max-width: 768px) {\n .keywordTicker-text {\n font-size: 1.5rem;\n padding: 0px 15px;\n }\n .keywordTicker__img img {\n max-height: 104px;\n left: -60px;\n }\n .keywordTicker__track {\n padding: 10px 0px;\n margin-left: -100px;\n }\n}\n@media only screen and (max-width: 484px) {\n .keywordTicker-text {\n font-size: 14px;\n }\n}";
13
13
  styleInject(css_248z);
14
14
 
15
15
  var KeywordTicker = function KeywordTicker(_ref) {
@@ -23,6 +23,11 @@ var KeywordTicker = function KeywordTicker(_ref) {
23
23
  _useState2 = _slicedToArray(_useState, 2),
24
24
  tracking = _useState2[0],
25
25
  setTracking = _useState2[1];
26
+ /* WCAG 2.2.2 自動移動內容需提供暫停控制;並尊重「減少動態效果」偏好預設暫停(WCAG 2.3.3) */
27
+ var _useState3 = useState(typeof window !== 'undefined' && window.matchMedia && window.matchMedia('(prefers-reduced-motion: reduce)').matches),
28
+ _useState4 = _slicedToArray(_useState3, 2),
29
+ paused = _useState4[0],
30
+ setPaused = _useState4[1];
26
31
  var _ref2 = tickerAttribute || {
27
32
  result: [],
28
33
  mounted: false,
@@ -121,24 +126,52 @@ var KeywordTicker = function KeywordTicker(_ref) {
121
126
  setTracking(initTracking);
122
127
  }
123
128
  }, [mounted, step]);
129
+
130
+ /* 暫停狀態同步到動畫(含 prefers-reduced-motion 預設暫停) */
131
+ useEffect(function () {
132
+ if (!tracking) return;
133
+ if (paused) tracking.pause();else tracking.play();
134
+ }, [tracking, paused]);
135
+
136
+ /* WCAG 2.1.1/2.4.7 跑馬燈連結為無限輪播重複複製且持續移動,鍵盤逐一 Tab 體驗惡劣:
137
+ 本體標記 aria-hidden 並將內部連結移出 Tab 順序(消費端另以等效清單提供鍵盤操作)。
138
+ 跑馬燈重渲染後需重設。 */
139
+ useEffect(function () {
140
+ if (track.current) {
141
+ track.current.querySelectorAll('a').forEach(function (a) {
142
+ return a.setAttribute('tabindex', '-1');
143
+ });
144
+ }
145
+ }, [result]);
124
146
  return /*#__PURE__*/React__default.createElement("div", {
125
147
  className: classNames('keywordTicker', className)
126
- }, leftImg && /*#__PURE__*/React__default.createElement("div", {
148
+ }, /*#__PURE__*/React__default.createElement("button", {
149
+ type: "button",
150
+ className: "keywordTicker__playToggle",
151
+ "aria-pressed": paused,
152
+ onClick: function onClick() {
153
+ return setPaused(!paused);
154
+ }
155
+ }, getIntl().formatMessage({
156
+ id: paused ? 'aria.ticker.play' : 'aria.ticker.pause'
157
+ })), leftImg && /*#__PURE__*/React__default.createElement("div", {
127
158
  className: "keywordTicker__img"
128
159
  }, /*#__PURE__*/React__default.createElement("img", {
129
160
  src: leftImg,
130
- alt: "hotKeyword"
161
+ alt: "",
162
+ "aria-hidden": "true"
131
163
  })), /*#__PURE__*/React__default.createElement("div", {
132
164
  className: "keywordTicker__track",
133
165
  ref: track,
134
166
  style: {
135
167
  backgroundColor: backgroundColor
136
168
  },
169
+ "aria-hidden": "true",
137
170
  onMouseEnter: function onMouseEnter() {
138
171
  return tracking === null || tracking === void 0 ? void 0 : tracking.pause();
139
172
  },
140
173
  onMouseLeave: function onMouseLeave() {
141
- return tracking === null || tracking === void 0 ? void 0 : tracking.play();
174
+ if (!paused && tracking) tracking.play();
142
175
  }
143
176
  }, /*#__PURE__*/React__default.createElement("div", {
144
177
  className: "keywordTicker__items",
@@ -5,11 +5,11 @@ import { c as classNames } from './index-b76a85f4.js';
5
5
  import { M as Modal } from './Modal-777fe87d.js';
6
6
  import { Typography } from '@material-ui/core';
7
7
  import { r as requireCreateSvgIcon, i as interopRequireDefault, a as interopRequireWildcard } from './createSvgIcon-e3803ee1.js';
8
+ import { getIntl } from './globalConfig';
8
9
  import { s as styleInject } from './style-inject.es-1f59c1d0.js';
9
10
  import '@material-ui/icons';
10
11
  import './Button-305b69a0.js';
11
12
  import './Spin-8dc60bfe.js';
12
- import './globalConfig';
13
13
  import './_commonjsHelpers-70de2c37.js';
14
14
  import './defaultTheme-ed7746fe.js';
15
15
  import 'react-is';
@@ -71,7 +71,18 @@ const KeywordList = _ref => {
71
71
  color: "textSecondary",
72
72
  className: "keywordList__item",
73
73
  key: i.toString(),
74
- onClick: () => onKeywordClick(keyword)
74
+ role: "button",
75
+ tabIndex: 0,
76
+ "aria-label": `${keyword}${getIntl().formatMessage({
77
+ id: 'aria.keyword.searchHint'
78
+ })}`,
79
+ onClick: () => onKeywordClick(keyword),
80
+ onKeyDown: event => {
81
+ if (event.key === 'Enter' || event.key === ' ') {
82
+ event.preventDefault();
83
+ onKeywordClick(keyword);
84
+ }
85
+ }
75
86
  }, /*#__PURE__*/React__default.createElement("div", {
76
87
  style: {
77
88
  color: textColor,
@@ -83,13 +94,27 @@ const KeywordList = _ref => {
83
94
  style: {
84
95
  backgroundColor
85
96
  },
86
- onClick: onMoreClick
97
+ role: "button",
98
+ tabIndex: 0,
99
+ "aria-haspopup": "dialog",
100
+ "aria-label": getIntl().formatMessage({
101
+ id: 'aria.keyword.more'
102
+ }),
103
+ onClick: onMoreClick,
104
+ onKeyDown: event => {
105
+ if (event.key === 'Enter' || event.key === ' ') {
106
+ event.preventDefault();
107
+ onMoreClick();
108
+ }
109
+ }
87
110
  }, /*#__PURE__*/React__default.createElement("div", {
88
111
  className: "keywordList__item__hover",
89
112
  style: {
90
113
  color: textColor
91
114
  }
92
- }, /*#__PURE__*/React__default.createElement(default_1, null))));
115
+ }, /*#__PURE__*/React__default.createElement(default_1, {
116
+ "aria-hidden": "true"
117
+ }))));
93
118
  };
94
119
  KeywordList.defaultProps = {
95
120
  className: undefined,
@@ -2,6 +2,7 @@ import React__default from 'react';
2
2
  import PropTypes from 'prop-types';
3
3
  import { c as classNames } from './index-b76a85f4.js';
4
4
  import { ExpandLess, ExpandMore } from '@material-ui/icons';
5
+ import { getIntl } from './globalConfig';
5
6
  import { s as styleInject } from './style-inject.es-1f59c1d0.js';
6
7
 
7
8
  var css_248z = ".moreButton {\n width: -moz-fit-content;\n width: fit-content;\n display: flex;\n align-items: center;\n position: relative;\n margin: 1rem 0rem;\n border-radius: 8px;\n padding: 1rem 2.5rem;\n -webkit-user-select: none;\n user-select: none;\n cursor: pointer;\n}\n.moreButton__mask {\n transition: all 0.3s ease-in-out;\n position: absolute;\n left: 0;\n top: 0;\n border-radius: 8px;\n width: 100%;\n height: 100%;\n opacity: 0;\n}\n.moreButton:hover .moreButton__mask {\n opacity: 1;\n}\n.moreButton--shadow {\n transition: all 0.3s ease-in-out;\n border: 3px solid #ffffff;\n position: relative;\n left: 0px;\n top: 0px;\n}\n.moreButton--shadow:hover {\n box-shadow: initial !important;\n left: 3px;\n top: 3px;\n}\n.moreButton--small {\n border: 0;\n padding: 0;\n left: 0px !important;\n top: 0px !important;\n background: transparent !important;\n box-shadow: initial !important;\n}\n.moreButton--small .moreButton__mask {\n opacity: 0 !important;\n}\n.moreButton__icon {\n display: flex;\n z-index: 1;\n}\n.moreButton__icon--small {\n font-size: 1.5rem;\n border-radius: 45px;\n color: white !important;\n}\n.moreButton__text {\n z-index: 1;\n font-size: 1.5rem;\n line-height: 1.5rem;\n transition: color 0.3s ease-in-out;\n}\n.moreButton__text--small {\n margin-left: 0.75rem;\n font-size: 1.5rem;\n color: #0c2a4d;\n}\n.moreButton__text--small:hover {\n text-decoration: underline;\n}";
@@ -16,7 +17,7 @@ var MoreButton = function MoreButton(props) {
16
17
  customExpandIcon = props.customExpandIcon;
17
18
  var expand = props.expand,
18
19
  setExpand = props.setExpand,
19
- _onClick = props.onClick,
20
+ onClick = props.onClick,
20
21
  formatMessage = props.formatMessage;
21
22
  var smallIcon = expand ? /*#__PURE__*/React__default.createElement(ExpandLess, {
22
23
  className: "moreButton__icon--small",
@@ -33,42 +34,62 @@ var MoreButton = function MoreButton(props) {
33
34
  var message = small ? smallMessage : 'common.watch.more';
34
35
  var largeIcon = customExpandIcon && /*#__PURE__*/React__default.createElement("img", {
35
36
  src: customExpandIcon,
36
- alt: "more"
37
+ alt: "",
38
+ "aria-hidden": "true"
37
39
  });
38
40
  var icon = small ? smallIcon : largeIcon;
39
- return /*#__PURE__*/React__default.createElement("div", {
40
- className: classNames('moreButton', {
41
- 'moreButton--shadow': enableShadow
42
- }, {
43
- 'moreButton--small': small
44
- }),
45
- style: {
46
- color: shadowColor || 'white',
47
- background: primaryColor,
48
- boxShadow: enableShadow ? "3px 3px 0 0 ".concat(shadowColor) : undefined
49
- },
50
- onClick: function onClick() {
51
- setExpand(!expand);
52
- _onClick();
53
- }
54
- }, !enableShadow && /*#__PURE__*/React__default.createElement("div", {
55
- className: "moreButton__mask",
56
- style: {
57
- background: secondaryColor
58
- }
59
- }), /*#__PURE__*/React__default.createElement("div", {
60
- className: "moreButton__icon"
61
- }, icon), /*#__PURE__*/React__default.createElement("div", {
62
- className: classNames('moreButton__text', {
63
- 'moreButton__text--small': small
64
- }),
65
- style: {
66
- color: small ? shadowColor || primaryColor : undefined,
67
- marginLeft: icon ? '0.5rem' : undefined
68
- }
69
- }, formatMessage ? formatMessage({
41
+ var handleAction = function handleAction() {
42
+ setExpand(!expand);
43
+ onClick();
44
+ };
45
+ var messageText = formatMessage ? formatMessage({
70
46
  id: message
71
- }) : message));
47
+ }) : message;
48
+ return (
49
+ /*#__PURE__*/
50
+ /* WCAG 2.1.1/4.1.2 看更多為互動元件:role="button" + tabIndex + 鍵盤操作,
51
+ 報讀補「點選後載入更多結果」預先提示、aria-expanded 表達展開狀態 */
52
+ React__default.createElement("div", {
53
+ className: classNames('moreButton', {
54
+ 'moreButton--shadow': enableShadow
55
+ }, {
56
+ 'moreButton--small': small
57
+ }),
58
+ role: "button",
59
+ tabIndex: 0,
60
+ "aria-expanded": expand,
61
+ "aria-label": "".concat(messageText).concat(getIntl().formatMessage({
62
+ id: 'aria.moreButton.hint'
63
+ })),
64
+ style: {
65
+ color: shadowColor || 'white',
66
+ background: primaryColor,
67
+ boxShadow: enableShadow ? "3px 3px 0 0 ".concat(shadowColor) : undefined
68
+ },
69
+ onClick: handleAction,
70
+ onKeyDown: function onKeyDown(event) {
71
+ if (event.key === 'Enter' || event.key === ' ') {
72
+ event.preventDefault();
73
+ handleAction();
74
+ }
75
+ }
76
+ }, !enableShadow && /*#__PURE__*/React__default.createElement("div", {
77
+ className: "moreButton__mask",
78
+ style: {
79
+ background: secondaryColor
80
+ }
81
+ }), /*#__PURE__*/React__default.createElement("div", {
82
+ className: "moreButton__icon"
83
+ }, icon), /*#__PURE__*/React__default.createElement("div", {
84
+ className: classNames('moreButton__text', {
85
+ 'moreButton__text--small': small
86
+ }),
87
+ style: {
88
+ color: small ? shadowColor || primaryColor : undefined,
89
+ marginLeft: icon ? '0.5rem' : undefined
90
+ }
91
+ }, messageText))
92
+ );
72
93
  };
73
94
  MoreButton.defaultProps = {
74
95
  primaryColor: '#271702',
@@ -1,6 +1,7 @@
1
- export { M as default } from './MoreButton-44d3b4fe.js';
1
+ export { M as default } from './MoreButton-692584cd.js';
2
2
  import 'react';
3
3
  import 'prop-types';
4
4
  import './index-b76a85f4.js';
5
5
  import '@material-ui/icons';
6
+ import './globalConfig';
6
7
  import './style-inject.es-1f59c1d0.js';
@@ -2,12 +2,13 @@ import { c as _objectWithoutProperties$1 } from './_rollupPluginBabelHelpers-a52
2
2
  import * as React$2 from 'react';
3
3
  import React__default, { Children, isValidElement, cloneElement } from 'react';
4
4
  import PropTypes from 'prop-types';
5
- import { d as defaultTheme, k as _objectWithoutProperties, o as _slicedToArray, _ as _extends, q as _objectWithoutPropertiesLoose, r as alpha, j as formatMuiErrorMessage } from './defaultTheme-ed7746fe.js';
5
+ import { k as _objectWithoutProperties, o as _slicedToArray, _ as _extends, q as _objectWithoutPropertiesLoose, r as alpha, j as formatMuiErrorMessage } from './defaultTheme-ed7746fe.js';
6
6
  import { u as useControlled, c as clsx, b as useEventCallback, w as withStyles, d as useIsFocusVisible, e as useForkRef, f as createSvgIcon, g as capitalize, h as debounce, r as requireCreateSvgIcon, i as interopRequireDefault, a as interopRequireWildcard } from './createSvgIcon-e3803ee1.js';
7
7
  import 'react-is';
8
- import { useTheme as useTheme$1 } from '@material-ui/styles';
8
+ import '@material-ui/styles';
9
9
  import './withTheme-2d778133.js';
10
10
  import { _ as _toConsumableArray } from './toConsumableArray-dbe8af76.js';
11
+ import { u as useTheme } from './useTheme-d16d02d9.js';
11
12
  import * as ReactDOM from 'react-dom';
12
13
  import ReactDOM__default from 'react-dom';
13
14
  import { c as classNames } from './index-b76a85f4.js';
@@ -15,12 +16,6 @@ import { IconButton } from '@material-ui/core';
15
16
  import { s as styleInject } from './style-inject.es-1f59c1d0.js';
16
17
  import './_commonjsHelpers-70de2c37.js';
17
18
 
18
- function useTheme() {
19
- var theme = useTheme$1() || defaultTheme;
20
-
21
- return theme;
22
- }
23
-
24
19
  function usePagination() {
25
20
  var props = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
26
21
 
@@ -2,7 +2,7 @@ import React__default, { useMemo, useEffect } from 'react';
2
2
  import PropTypes from 'prop-types';
3
3
  import { c as classNames } from './index-b76a85f4.js';
4
4
  import { e as event, d as d3Select, a as dispatch, c as customEvent, D as DragEvent, q as quadtree, m as map, t as timer, T as Transform, i as identity, b as interrupt, o as ordinal, f as category10 } from './transform-3a04288b.js';
5
- import { E as ExtraTools } from './ExtraTools-8d2ef84d.js';
5
+ import { E as ExtraTools } from './ExtraTools-55f66039.js';
6
6
  import { s as styleInject } from './style-inject.es-1f59c1d0.js';
7
7
  import './_rollupPluginBabelHelpers-a52356f6.js';
8
8
  import './_commonjsHelpers-70de2c37.js';
@@ -3,6 +3,11 @@ import React__default from 'react';
3
3
  import PropTypes from 'prop-types';
4
4
  import { c as classNames } from './index-b76a85f4.js';
5
5
  import { FormControl, Select as Select$1, CircularProgress, MenuItem } from '@material-ui/core';
6
+ import './defaultTheme-ed7746fe.js';
7
+ import 'react-is';
8
+ import '@material-ui/styles';
9
+ import { u as useTheme } from './useTheme-d16d02d9.js';
10
+ import './withTheme-2d778133.js';
6
11
  import { E as Empty } from './Empty-bf77164f.js';
7
12
  import { s as styleInject } from './style-inject.es-1f59c1d0.js';
8
13
 
@@ -25,6 +30,12 @@ var Select = function Select(props) {
25
30
  _onChange = props.onChange,
26
31
  ariaLabel = props.ariaLabel,
27
32
  ariaLabelledby = props.ariaLabelledby;
33
+ /* WCAG 1.4.3 提示字顏色依主題深淺自動選色:select.scss 的 #6b6130 只適用淺底,
34
+ 深色主題(palette.type=dark,如 ocean 深色 Modal)需改亮灰(WAVE 實測「請輸入 年齡」被抓) */
35
+ var theme = useTheme();
36
+ var placeholderStyle = theme && theme.palette && theme.palette.type === 'dark' ? {
37
+ color: '#bdbdbd'
38
+ } : undefined;
28
39
  var itemFind = function itemFind(key) {
29
40
  return (options || []).find(function (option) {
30
41
  return _typeof(option) === 'object' ? key === option.value : key === option;
@@ -52,9 +63,12 @@ var Select = function Select(props) {
52
63
  renderValue: function renderValue(id) {
53
64
  var finder = itemFind(id);
54
65
  var content = _typeof(finder) === 'object' ? finder.label : finder;
55
- if (!id && id !== 0 || id.length === 0) content = /*#__PURE__*/React__default.createElement("span", {
56
- className: "select__placeholder"
57
- }, placeholder);
66
+ if (!id && id !== 0 || id.length === 0) {
67
+ content = /*#__PURE__*/React__default.createElement("span", {
68
+ className: "select__placeholder",
69
+ style: placeholderStyle
70
+ }, placeholder);
71
+ }
58
72
  return /*#__PURE__*/React__default.createElement(React__default.Fragment, null, content, loading && /*#__PURE__*/React__default.createElement(CircularProgress, {
59
73
  size: 16,
60
74
  style: {
@@ -1,8 +1,13 @@
1
- export { S as default } from './Select-ac580a1f.js';
1
+ export { S as default } from './Select-e0790135.js';
2
2
  import './_rollupPluginBabelHelpers-a52356f6.js';
3
3
  import 'react';
4
4
  import 'prop-types';
5
5
  import './index-b76a85f4.js';
6
6
  import '@material-ui/core';
7
+ import './defaultTheme-ed7746fe.js';
8
+ import 'react-is';
9
+ import '@material-ui/styles';
10
+ import './useTheme-d16d02d9.js';
11
+ import './withTheme-2d778133.js';
7
12
  import './Empty-bf77164f.js';
8
13
  import './style-inject.es-1f59c1d0.js';
@@ -63,7 +63,18 @@ var zhtw = {
63
63
  "aria.modal.close": "關閉視窗",
64
64
  "aria.newWindow": "(另開新視窗)",
65
65
  "aria.vcode.image": "驗證碼圖片,如無法辨識可刷新驗證碼",
66
- "aria.vcode.refresh": "刷新驗證碼"
66
+ "aria.vcode.refresh": "刷新驗證碼",
67
+ "aria.footer.nmtlLogo": "國立臺灣文學館(另開新視窗)",
68
+ "aria.opensDialog": "(開啟對話框)",
69
+ "aria.ticker.pause": "暫停關鍵字跑馬燈",
70
+ "aria.ticker.play": "播放關鍵字跑馬燈",
71
+ "aria.moreButton.hint": "(點選後載入更多結果)",
72
+ "aria.keyword.searchHint": "(關鍵字,點選後顯示相關作品)",
73
+ "aria.keyword.more": "顯示更多關鍵字(開啟對話框)",
74
+ "aria.vcode.audioPlay": "播放驗證碼語音",
75
+ "aria.vcode.audioIntro": "驗證碼為:",
76
+ "aria.vcode.audioUnsupported": "瀏覽器不支援語音合成,請刷新驗證碼或改用圖片辨識",
77
+ "aria.vcode.refreshed": "驗證碼已更新"
67
78
  };
68
79
 
69
80
  var zhcn = {
@@ -115,7 +126,18 @@ var zhcn = {
115
126
  "aria.modal.close": "关闭视窗",
116
127
  "aria.newWindow": "(另开新视窗)",
117
128
  "aria.vcode.image": "验证码图片,如无法辨识可刷新验证码",
118
- "aria.vcode.refresh": "刷新验证码"
129
+ "aria.vcode.refresh": "刷新验证码",
130
+ "aria.footer.nmtlLogo": "国立台湾文学馆(另开新窗口)",
131
+ "aria.opensDialog": "(开启对话框)",
132
+ "aria.ticker.pause": "暂停关键字跑马灯",
133
+ "aria.ticker.play": "播放关键字跑马灯",
134
+ "aria.moreButton.hint": "(点选后载入更多结果)",
135
+ "aria.keyword.searchHint": "(关键字,点选后显示相关作品)",
136
+ "aria.keyword.more": "显示更多关键字(开启对话框)",
137
+ "aria.vcode.audioPlay": "播放验证码语音",
138
+ "aria.vcode.audioIntro": "验证码为:",
139
+ "aria.vcode.audioUnsupported": "浏览器不支持语音合成,请刷新验证码或改用图片辨识",
140
+ "aria.vcode.refreshed": "验证码已更新"
119
141
  };
120
142
 
121
143
  var enus = {
@@ -167,7 +189,18 @@ var enus = {
167
189
  "aria.modal.close": "Close dialog",
168
190
  "aria.newWindow": " (opens in new window)",
169
191
  "aria.vcode.image": "CAPTCHA image, refresh if unreadable",
170
- "aria.vcode.refresh": "Refresh CAPTCHA"
192
+ "aria.vcode.refresh": "Refresh CAPTCHA",
193
+ "aria.footer.nmtlLogo": "National Museum of Taiwan Literature (opens in new window)",
194
+ "aria.opensDialog": " (opens a dialog)",
195
+ "aria.ticker.pause": "Pause keyword ticker",
196
+ "aria.ticker.play": "Play keyword ticker",
197
+ "aria.moreButton.hint": " (click to load more results)",
198
+ "aria.keyword.searchHint": " (keyword, click to show related works)",
199
+ "aria.keyword.more": "Show more keywords (opens a dialog)",
200
+ "aria.vcode.audioPlay": "Play verification code audio",
201
+ "aria.vcode.audioIntro": "The verification code is:",
202
+ "aria.vcode.audioUnsupported": "Speech synthesis not supported; please refresh the code",
203
+ "aria.vcode.refreshed": "Verification code refreshed"
171
204
  };
172
205
 
173
206
  var _languages;
@@ -0,0 +1,11 @@
1
+ import { useTheme as useTheme$1 } from '@material-ui/styles';
2
+ import 'react';
3
+ import { d as defaultTheme } from './defaultTheme-ed7746fe.js';
4
+
5
+ function useTheme() {
6
+ var theme = useTheme$1() || defaultTheme;
7
+
8
+ return theme;
9
+ }
10
+
11
+ export { useTheme as u };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@daoyi/nmtl-ui",
3
- "version": "2.0.1-beta.97",
3
+ "version": "2.0.1-beta.99",
4
4
  "description": "This project is to be used as a starter kit for building React component using Storybook and Rollup",
5
5
  "author": "daoyi",
6
6
  "main": "lib/index.js",