mokkun 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mokkun.js","sources":["../node_modules/.pnpm/js-yaml@4.1.1/node_modules/js-yaml/dist/js-yaml.mjs","../src/parser/yaml-parser.ts","../src/renderer/utils/dom.ts","../src/renderer/utils/field-helpers.ts","../src/renderer/components/input.ts","../src/renderer/components/textarea.ts","../src/renderer/components/select.ts","../src/renderer/components/radio.ts","../src/renderer/components/checkbox.ts","../src/renderer/components/combobox.ts","../src/renderer/components/heading.ts","../src/renderer/components/duration-picker.ts","../src/renderer/components/duration-input.ts","../src/renderer/components/pagination.ts","../src/renderer/components/toggle.ts","../src/renderer/components/badge.ts","../src/renderer/components/browser.ts","../src/renderer/components/calendar.ts","../src/renderer/components/tooltip.ts","../src/renderer/components/float-area.ts","../src/renderer/components/loader.ts","../src/renderer/components/notification-bar.ts","../src/renderer/components/response-message.ts","../src/renderer/components/timeline.ts","../src/renderer/components/chip.ts","../src/renderer/components/status-label.ts","../src/renderer/components/segmented-control.ts","../src/renderer/components/tabs.ts","../src/renderer/components/line-clamp.ts","../src/renderer/components/disclosure.ts","../src/renderer/components/accordion-panel.ts","../src/renderer/components/section-nav.ts","../src/renderer/components/definition-list.ts","../src/renderer/components/stepper.ts","../src/renderer/components/information-panel.ts","../src/renderer/components/dropdown.ts","../src/renderer/components/delete-confirm-dialog.ts","../src/renderer/utils/dummy-data.ts","../src/renderer/components/data-table.ts","../src/renderer/components/photo-manager-renderer.ts","../src/renderer/components/form-fields.ts","../src/renderer/components/layout.ts","../src/renderer/screen-renderer.ts","../src/renderer/action-handler.ts","../src/loader/file-loader.ts","../src/types/theme.ts","../src/theme/theme-manager.ts","../src/lib.ts"],"sourcesContent":["\n/*! js-yaml 4.1.1 https://github.com/nodeca/js-yaml @license MIT */\nfunction isNothing(subject) {\n return (typeof subject === 'undefined') || (subject === null);\n}\n\n\nfunction isObject(subject) {\n return (typeof subject === 'object') && (subject !== null);\n}\n\n\nfunction toArray(sequence) {\n if (Array.isArray(sequence)) return sequence;\n else if (isNothing(sequence)) return [];\n\n return [ sequence ];\n}\n\n\nfunction extend(target, source) {\n var index, length, key, sourceKeys;\n\n if (source) {\n sourceKeys = Object.keys(source);\n\n for (index = 0, length = sourceKeys.length; index < length; index += 1) {\n key = sourceKeys[index];\n target[key] = source[key];\n }\n }\n\n return target;\n}\n\n\nfunction repeat(string, count) {\n var result = '', cycle;\n\n for (cycle = 0; cycle < count; cycle += 1) {\n result += string;\n }\n\n return result;\n}\n\n\nfunction isNegativeZero(number) {\n return (number === 0) && (Number.NEGATIVE_INFINITY === 1 / number);\n}\n\n\nvar isNothing_1 = isNothing;\nvar isObject_1 = isObject;\nvar toArray_1 = toArray;\nvar repeat_1 = repeat;\nvar isNegativeZero_1 = isNegativeZero;\nvar extend_1 = extend;\n\nvar common = {\n\tisNothing: isNothing_1,\n\tisObject: isObject_1,\n\ttoArray: toArray_1,\n\trepeat: repeat_1,\n\tisNegativeZero: isNegativeZero_1,\n\textend: extend_1\n};\n\n// YAML error class. http://stackoverflow.com/questions/8458984\n\n\nfunction formatError(exception, compact) {\n var where = '', message = exception.reason || '(unknown reason)';\n\n if (!exception.mark) return message;\n\n if (exception.mark.name) {\n where += 'in \"' + exception.mark.name + '\" ';\n }\n\n where += '(' + (exception.mark.line + 1) + ':' + (exception.mark.column + 1) + ')';\n\n if (!compact && exception.mark.snippet) {\n where += '\\n\\n' + exception.mark.snippet;\n }\n\n return message + ' ' + where;\n}\n\n\nfunction YAMLException$1(reason, mark) {\n // Super constructor\n Error.call(this);\n\n this.name = 'YAMLException';\n this.reason = reason;\n this.mark = mark;\n this.message = formatError(this, false);\n\n // Include stack trace in error object\n if (Error.captureStackTrace) {\n // Chrome and NodeJS\n Error.captureStackTrace(this, this.constructor);\n } else {\n // FF, IE 10+ and Safari 6+. Fallback for others\n this.stack = (new Error()).stack || '';\n }\n}\n\n\n// Inherit from Error\nYAMLException$1.prototype = Object.create(Error.prototype);\nYAMLException$1.prototype.constructor = YAMLException$1;\n\n\nYAMLException$1.prototype.toString = function toString(compact) {\n return this.name + ': ' + formatError(this, compact);\n};\n\n\nvar exception = YAMLException$1;\n\n// get snippet for a single line, respecting maxLength\nfunction getLine(buffer, lineStart, lineEnd, position, maxLineLength) {\n var head = '';\n var tail = '';\n var maxHalfLength = Math.floor(maxLineLength / 2) - 1;\n\n if (position - lineStart > maxHalfLength) {\n head = ' ... ';\n lineStart = position - maxHalfLength + head.length;\n }\n\n if (lineEnd - position > maxHalfLength) {\n tail = ' ...';\n lineEnd = position + maxHalfLength - tail.length;\n }\n\n return {\n str: head + buffer.slice(lineStart, lineEnd).replace(/\\t/g, '→') + tail,\n pos: position - lineStart + head.length // relative position\n };\n}\n\n\nfunction padStart(string, max) {\n return common.repeat(' ', max - string.length) + string;\n}\n\n\nfunction makeSnippet(mark, options) {\n options = Object.create(options || null);\n\n if (!mark.buffer) return null;\n\n if (!options.maxLength) options.maxLength = 79;\n if (typeof options.indent !== 'number') options.indent = 1;\n if (typeof options.linesBefore !== 'number') options.linesBefore = 3;\n if (typeof options.linesAfter !== 'number') options.linesAfter = 2;\n\n var re = /\\r?\\n|\\r|\\0/g;\n var lineStarts = [ 0 ];\n var lineEnds = [];\n var match;\n var foundLineNo = -1;\n\n while ((match = re.exec(mark.buffer))) {\n lineEnds.push(match.index);\n lineStarts.push(match.index + match[0].length);\n\n if (mark.position <= match.index && foundLineNo < 0) {\n foundLineNo = lineStarts.length - 2;\n }\n }\n\n if (foundLineNo < 0) foundLineNo = lineStarts.length - 1;\n\n var result = '', i, line;\n var lineNoLength = Math.min(mark.line + options.linesAfter, lineEnds.length).toString().length;\n var maxLineLength = options.maxLength - (options.indent + lineNoLength + 3);\n\n for (i = 1; i <= options.linesBefore; i++) {\n if (foundLineNo - i < 0) break;\n line = getLine(\n mark.buffer,\n lineStarts[foundLineNo - i],\n lineEnds[foundLineNo - i],\n mark.position - (lineStarts[foundLineNo] - lineStarts[foundLineNo - i]),\n maxLineLength\n );\n result = common.repeat(' ', options.indent) + padStart((mark.line - i + 1).toString(), lineNoLength) +\n ' | ' + line.str + '\\n' + result;\n }\n\n line = getLine(mark.buffer, lineStarts[foundLineNo], lineEnds[foundLineNo], mark.position, maxLineLength);\n result += common.repeat(' ', options.indent) + padStart((mark.line + 1).toString(), lineNoLength) +\n ' | ' + line.str + '\\n';\n result += common.repeat('-', options.indent + lineNoLength + 3 + line.pos) + '^' + '\\n';\n\n for (i = 1; i <= options.linesAfter; i++) {\n if (foundLineNo + i >= lineEnds.length) break;\n line = getLine(\n mark.buffer,\n lineStarts[foundLineNo + i],\n lineEnds[foundLineNo + i],\n mark.position - (lineStarts[foundLineNo] - lineStarts[foundLineNo + i]),\n maxLineLength\n );\n result += common.repeat(' ', options.indent) + padStart((mark.line + i + 1).toString(), lineNoLength) +\n ' | ' + line.str + '\\n';\n }\n\n return result.replace(/\\n$/, '');\n}\n\n\nvar snippet = makeSnippet;\n\nvar TYPE_CONSTRUCTOR_OPTIONS = [\n 'kind',\n 'multi',\n 'resolve',\n 'construct',\n 'instanceOf',\n 'predicate',\n 'represent',\n 'representName',\n 'defaultStyle',\n 'styleAliases'\n];\n\nvar YAML_NODE_KINDS = [\n 'scalar',\n 'sequence',\n 'mapping'\n];\n\nfunction compileStyleAliases(map) {\n var result = {};\n\n if (map !== null) {\n Object.keys(map).forEach(function (style) {\n map[style].forEach(function (alias) {\n result[String(alias)] = style;\n });\n });\n }\n\n return result;\n}\n\nfunction Type$1(tag, options) {\n options = options || {};\n\n Object.keys(options).forEach(function (name) {\n if (TYPE_CONSTRUCTOR_OPTIONS.indexOf(name) === -1) {\n throw new exception('Unknown option \"' + name + '\" is met in definition of \"' + tag + '\" YAML type.');\n }\n });\n\n // TODO: Add tag format check.\n this.options = options; // keep original options in case user wants to extend this type later\n this.tag = tag;\n this.kind = options['kind'] || null;\n this.resolve = options['resolve'] || function () { return true; };\n this.construct = options['construct'] || function (data) { return data; };\n this.instanceOf = options['instanceOf'] || null;\n this.predicate = options['predicate'] || null;\n this.represent = options['represent'] || null;\n this.representName = options['representName'] || null;\n this.defaultStyle = options['defaultStyle'] || null;\n this.multi = options['multi'] || false;\n this.styleAliases = compileStyleAliases(options['styleAliases'] || null);\n\n if (YAML_NODE_KINDS.indexOf(this.kind) === -1) {\n throw new exception('Unknown kind \"' + this.kind + '\" is specified for \"' + tag + '\" YAML type.');\n }\n}\n\nvar type = Type$1;\n\n/*eslint-disable max-len*/\n\n\n\n\n\nfunction compileList(schema, name) {\n var result = [];\n\n schema[name].forEach(function (currentType) {\n var newIndex = result.length;\n\n result.forEach(function (previousType, previousIndex) {\n if (previousType.tag === currentType.tag &&\n previousType.kind === currentType.kind &&\n previousType.multi === currentType.multi) {\n\n newIndex = previousIndex;\n }\n });\n\n result[newIndex] = currentType;\n });\n\n return result;\n}\n\n\nfunction compileMap(/* lists... */) {\n var result = {\n scalar: {},\n sequence: {},\n mapping: {},\n fallback: {},\n multi: {\n scalar: [],\n sequence: [],\n mapping: [],\n fallback: []\n }\n }, index, length;\n\n function collectType(type) {\n if (type.multi) {\n result.multi[type.kind].push(type);\n result.multi['fallback'].push(type);\n } else {\n result[type.kind][type.tag] = result['fallback'][type.tag] = type;\n }\n }\n\n for (index = 0, length = arguments.length; index < length; index += 1) {\n arguments[index].forEach(collectType);\n }\n return result;\n}\n\n\nfunction Schema$1(definition) {\n return this.extend(definition);\n}\n\n\nSchema$1.prototype.extend = function extend(definition) {\n var implicit = [];\n var explicit = [];\n\n if (definition instanceof type) {\n // Schema.extend(type)\n explicit.push(definition);\n\n } else if (Array.isArray(definition)) {\n // Schema.extend([ type1, type2, ... ])\n explicit = explicit.concat(definition);\n\n } else if (definition && (Array.isArray(definition.implicit) || Array.isArray(definition.explicit))) {\n // Schema.extend({ explicit: [ type1, type2, ... ], implicit: [ type1, type2, ... ] })\n if (definition.implicit) implicit = implicit.concat(definition.implicit);\n if (definition.explicit) explicit = explicit.concat(definition.explicit);\n\n } else {\n throw new exception('Schema.extend argument should be a Type, [ Type ], ' +\n 'or a schema definition ({ implicit: [...], explicit: [...] })');\n }\n\n implicit.forEach(function (type$1) {\n if (!(type$1 instanceof type)) {\n throw new exception('Specified list of YAML types (or a single Type object) contains a non-Type object.');\n }\n\n if (type$1.loadKind && type$1.loadKind !== 'scalar') {\n throw new exception('There is a non-scalar type in the implicit list of a schema. Implicit resolving of such types is not supported.');\n }\n\n if (type$1.multi) {\n throw new exception('There is a multi type in the implicit list of a schema. Multi tags can only be listed as explicit.');\n }\n });\n\n explicit.forEach(function (type$1) {\n if (!(type$1 instanceof type)) {\n throw new exception('Specified list of YAML types (or a single Type object) contains a non-Type object.');\n }\n });\n\n var result = Object.create(Schema$1.prototype);\n\n result.implicit = (this.implicit || []).concat(implicit);\n result.explicit = (this.explicit || []).concat(explicit);\n\n result.compiledImplicit = compileList(result, 'implicit');\n result.compiledExplicit = compileList(result, 'explicit');\n result.compiledTypeMap = compileMap(result.compiledImplicit, result.compiledExplicit);\n\n return result;\n};\n\n\nvar schema = Schema$1;\n\nvar str = new type('tag:yaml.org,2002:str', {\n kind: 'scalar',\n construct: function (data) { return data !== null ? data : ''; }\n});\n\nvar seq = new type('tag:yaml.org,2002:seq', {\n kind: 'sequence',\n construct: function (data) { return data !== null ? data : []; }\n});\n\nvar map = new type('tag:yaml.org,2002:map', {\n kind: 'mapping',\n construct: function (data) { return data !== null ? data : {}; }\n});\n\nvar failsafe = new schema({\n explicit: [\n str,\n seq,\n map\n ]\n});\n\nfunction resolveYamlNull(data) {\n if (data === null) return true;\n\n var max = data.length;\n\n return (max === 1 && data === '~') ||\n (max === 4 && (data === 'null' || data === 'Null' || data === 'NULL'));\n}\n\nfunction constructYamlNull() {\n return null;\n}\n\nfunction isNull(object) {\n return object === null;\n}\n\nvar _null = new type('tag:yaml.org,2002:null', {\n kind: 'scalar',\n resolve: resolveYamlNull,\n construct: constructYamlNull,\n predicate: isNull,\n represent: {\n canonical: function () { return '~'; },\n lowercase: function () { return 'null'; },\n uppercase: function () { return 'NULL'; },\n camelcase: function () { return 'Null'; },\n empty: function () { return ''; }\n },\n defaultStyle: 'lowercase'\n});\n\nfunction resolveYamlBoolean(data) {\n if (data === null) return false;\n\n var max = data.length;\n\n return (max === 4 && (data === 'true' || data === 'True' || data === 'TRUE')) ||\n (max === 5 && (data === 'false' || data === 'False' || data === 'FALSE'));\n}\n\nfunction constructYamlBoolean(data) {\n return data === 'true' ||\n data === 'True' ||\n data === 'TRUE';\n}\n\nfunction isBoolean(object) {\n return Object.prototype.toString.call(object) === '[object Boolean]';\n}\n\nvar bool = new type('tag:yaml.org,2002:bool', {\n kind: 'scalar',\n resolve: resolveYamlBoolean,\n construct: constructYamlBoolean,\n predicate: isBoolean,\n represent: {\n lowercase: function (object) { return object ? 'true' : 'false'; },\n uppercase: function (object) { return object ? 'TRUE' : 'FALSE'; },\n camelcase: function (object) { return object ? 'True' : 'False'; }\n },\n defaultStyle: 'lowercase'\n});\n\nfunction isHexCode(c) {\n return ((0x30/* 0 */ <= c) && (c <= 0x39/* 9 */)) ||\n ((0x41/* A */ <= c) && (c <= 0x46/* F */)) ||\n ((0x61/* a */ <= c) && (c <= 0x66/* f */));\n}\n\nfunction isOctCode(c) {\n return ((0x30/* 0 */ <= c) && (c <= 0x37/* 7 */));\n}\n\nfunction isDecCode(c) {\n return ((0x30/* 0 */ <= c) && (c <= 0x39/* 9 */));\n}\n\nfunction resolveYamlInteger(data) {\n if (data === null) return false;\n\n var max = data.length,\n index = 0,\n hasDigits = false,\n ch;\n\n if (!max) return false;\n\n ch = data[index];\n\n // sign\n if (ch === '-' || ch === '+') {\n ch = data[++index];\n }\n\n if (ch === '0') {\n // 0\n if (index + 1 === max) return true;\n ch = data[++index];\n\n // base 2, base 8, base 16\n\n if (ch === 'b') {\n // base 2\n index++;\n\n for (; index < max; index++) {\n ch = data[index];\n if (ch === '_') continue;\n if (ch !== '0' && ch !== '1') return false;\n hasDigits = true;\n }\n return hasDigits && ch !== '_';\n }\n\n\n if (ch === 'x') {\n // base 16\n index++;\n\n for (; index < max; index++) {\n ch = data[index];\n if (ch === '_') continue;\n if (!isHexCode(data.charCodeAt(index))) return false;\n hasDigits = true;\n }\n return hasDigits && ch !== '_';\n }\n\n\n if (ch === 'o') {\n // base 8\n index++;\n\n for (; index < max; index++) {\n ch = data[index];\n if (ch === '_') continue;\n if (!isOctCode(data.charCodeAt(index))) return false;\n hasDigits = true;\n }\n return hasDigits && ch !== '_';\n }\n }\n\n // base 10 (except 0)\n\n // value should not start with `_`;\n if (ch === '_') return false;\n\n for (; index < max; index++) {\n ch = data[index];\n if (ch === '_') continue;\n if (!isDecCode(data.charCodeAt(index))) {\n return false;\n }\n hasDigits = true;\n }\n\n // Should have digits and should not end with `_`\n if (!hasDigits || ch === '_') return false;\n\n return true;\n}\n\nfunction constructYamlInteger(data) {\n var value = data, sign = 1, ch;\n\n if (value.indexOf('_') !== -1) {\n value = value.replace(/_/g, '');\n }\n\n ch = value[0];\n\n if (ch === '-' || ch === '+') {\n if (ch === '-') sign = -1;\n value = value.slice(1);\n ch = value[0];\n }\n\n if (value === '0') return 0;\n\n if (ch === '0') {\n if (value[1] === 'b') return sign * parseInt(value.slice(2), 2);\n if (value[1] === 'x') return sign * parseInt(value.slice(2), 16);\n if (value[1] === 'o') return sign * parseInt(value.slice(2), 8);\n }\n\n return sign * parseInt(value, 10);\n}\n\nfunction isInteger(object) {\n return (Object.prototype.toString.call(object)) === '[object Number]' &&\n (object % 1 === 0 && !common.isNegativeZero(object));\n}\n\nvar int = new type('tag:yaml.org,2002:int', {\n kind: 'scalar',\n resolve: resolveYamlInteger,\n construct: constructYamlInteger,\n predicate: isInteger,\n represent: {\n binary: function (obj) { return obj >= 0 ? '0b' + obj.toString(2) : '-0b' + obj.toString(2).slice(1); },\n octal: function (obj) { return obj >= 0 ? '0o' + obj.toString(8) : '-0o' + obj.toString(8).slice(1); },\n decimal: function (obj) { return obj.toString(10); },\n /* eslint-disable max-len */\n hexadecimal: function (obj) { return obj >= 0 ? '0x' + obj.toString(16).toUpperCase() : '-0x' + obj.toString(16).toUpperCase().slice(1); }\n },\n defaultStyle: 'decimal',\n styleAliases: {\n binary: [ 2, 'bin' ],\n octal: [ 8, 'oct' ],\n decimal: [ 10, 'dec' ],\n hexadecimal: [ 16, 'hex' ]\n }\n});\n\nvar YAML_FLOAT_PATTERN = new RegExp(\n // 2.5e4, 2.5 and integers\n '^(?:[-+]?(?:[0-9][0-9_]*)(?:\\\\.[0-9_]*)?(?:[eE][-+]?[0-9]+)?' +\n // .2e4, .2\n // special case, seems not from spec\n '|\\\\.[0-9_]+(?:[eE][-+]?[0-9]+)?' +\n // .inf\n '|[-+]?\\\\.(?:inf|Inf|INF)' +\n // .nan\n '|\\\\.(?:nan|NaN|NAN))$');\n\nfunction resolveYamlFloat(data) {\n if (data === null) return false;\n\n if (!YAML_FLOAT_PATTERN.test(data) ||\n // Quick hack to not allow integers end with `_`\n // Probably should update regexp & check speed\n data[data.length - 1] === '_') {\n return false;\n }\n\n return true;\n}\n\nfunction constructYamlFloat(data) {\n var value, sign;\n\n value = data.replace(/_/g, '').toLowerCase();\n sign = value[0] === '-' ? -1 : 1;\n\n if ('+-'.indexOf(value[0]) >= 0) {\n value = value.slice(1);\n }\n\n if (value === '.inf') {\n return (sign === 1) ? Number.POSITIVE_INFINITY : Number.NEGATIVE_INFINITY;\n\n } else if (value === '.nan') {\n return NaN;\n }\n return sign * parseFloat(value, 10);\n}\n\n\nvar SCIENTIFIC_WITHOUT_DOT = /^[-+]?[0-9]+e/;\n\nfunction representYamlFloat(object, style) {\n var res;\n\n if (isNaN(object)) {\n switch (style) {\n case 'lowercase': return '.nan';\n case 'uppercase': return '.NAN';\n case 'camelcase': return '.NaN';\n }\n } else if (Number.POSITIVE_INFINITY === object) {\n switch (style) {\n case 'lowercase': return '.inf';\n case 'uppercase': return '.INF';\n case 'camelcase': return '.Inf';\n }\n } else if (Number.NEGATIVE_INFINITY === object) {\n switch (style) {\n case 'lowercase': return '-.inf';\n case 'uppercase': return '-.INF';\n case 'camelcase': return '-.Inf';\n }\n } else if (common.isNegativeZero(object)) {\n return '-0.0';\n }\n\n res = object.toString(10);\n\n // JS stringifier can build scientific format without dots: 5e-100,\n // while YAML requres dot: 5.e-100. Fix it with simple hack\n\n return SCIENTIFIC_WITHOUT_DOT.test(res) ? res.replace('e', '.e') : res;\n}\n\nfunction isFloat(object) {\n return (Object.prototype.toString.call(object) === '[object Number]') &&\n (object % 1 !== 0 || common.isNegativeZero(object));\n}\n\nvar float = new type('tag:yaml.org,2002:float', {\n kind: 'scalar',\n resolve: resolveYamlFloat,\n construct: constructYamlFloat,\n predicate: isFloat,\n represent: representYamlFloat,\n defaultStyle: 'lowercase'\n});\n\nvar json = failsafe.extend({\n implicit: [\n _null,\n bool,\n int,\n float\n ]\n});\n\nvar core = json;\n\nvar YAML_DATE_REGEXP = new RegExp(\n '^([0-9][0-9][0-9][0-9])' + // [1] year\n '-([0-9][0-9])' + // [2] month\n '-([0-9][0-9])$'); // [3] day\n\nvar YAML_TIMESTAMP_REGEXP = new RegExp(\n '^([0-9][0-9][0-9][0-9])' + // [1] year\n '-([0-9][0-9]?)' + // [2] month\n '-([0-9][0-9]?)' + // [3] day\n '(?:[Tt]|[ \\\\t]+)' + // ...\n '([0-9][0-9]?)' + // [4] hour\n ':([0-9][0-9])' + // [5] minute\n ':([0-9][0-9])' + // [6] second\n '(?:\\\\.([0-9]*))?' + // [7] fraction\n '(?:[ \\\\t]*(Z|([-+])([0-9][0-9]?)' + // [8] tz [9] tz_sign [10] tz_hour\n '(?::([0-9][0-9]))?))?$'); // [11] tz_minute\n\nfunction resolveYamlTimestamp(data) {\n if (data === null) return false;\n if (YAML_DATE_REGEXP.exec(data) !== null) return true;\n if (YAML_TIMESTAMP_REGEXP.exec(data) !== null) return true;\n return false;\n}\n\nfunction constructYamlTimestamp(data) {\n var match, year, month, day, hour, minute, second, fraction = 0,\n delta = null, tz_hour, tz_minute, date;\n\n match = YAML_DATE_REGEXP.exec(data);\n if (match === null) match = YAML_TIMESTAMP_REGEXP.exec(data);\n\n if (match === null) throw new Error('Date resolve error');\n\n // match: [1] year [2] month [3] day\n\n year = +(match[1]);\n month = +(match[2]) - 1; // JS month starts with 0\n day = +(match[3]);\n\n if (!match[4]) { // no hour\n return new Date(Date.UTC(year, month, day));\n }\n\n // match: [4] hour [5] minute [6] second [7] fraction\n\n hour = +(match[4]);\n minute = +(match[5]);\n second = +(match[6]);\n\n if (match[7]) {\n fraction = match[7].slice(0, 3);\n while (fraction.length < 3) { // milli-seconds\n fraction += '0';\n }\n fraction = +fraction;\n }\n\n // match: [8] tz [9] tz_sign [10] tz_hour [11] tz_minute\n\n if (match[9]) {\n tz_hour = +(match[10]);\n tz_minute = +(match[11] || 0);\n delta = (tz_hour * 60 + tz_minute) * 60000; // delta in mili-seconds\n if (match[9] === '-') delta = -delta;\n }\n\n date = new Date(Date.UTC(year, month, day, hour, minute, second, fraction));\n\n if (delta) date.setTime(date.getTime() - delta);\n\n return date;\n}\n\nfunction representYamlTimestamp(object /*, style*/) {\n return object.toISOString();\n}\n\nvar timestamp = new type('tag:yaml.org,2002:timestamp', {\n kind: 'scalar',\n resolve: resolveYamlTimestamp,\n construct: constructYamlTimestamp,\n instanceOf: Date,\n represent: representYamlTimestamp\n});\n\nfunction resolveYamlMerge(data) {\n return data === '<<' || data === null;\n}\n\nvar merge = new type('tag:yaml.org,2002:merge', {\n kind: 'scalar',\n resolve: resolveYamlMerge\n});\n\n/*eslint-disable no-bitwise*/\n\n\n\n\n\n// [ 64, 65, 66 ] -> [ padding, CR, LF ]\nvar BASE64_MAP = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=\\n\\r';\n\n\nfunction resolveYamlBinary(data) {\n if (data === null) return false;\n\n var code, idx, bitlen = 0, max = data.length, map = BASE64_MAP;\n\n // Convert one by one.\n for (idx = 0; idx < max; idx++) {\n code = map.indexOf(data.charAt(idx));\n\n // Skip CR/LF\n if (code > 64) continue;\n\n // Fail on illegal characters\n if (code < 0) return false;\n\n bitlen += 6;\n }\n\n // If there are any bits left, source was corrupted\n return (bitlen % 8) === 0;\n}\n\nfunction constructYamlBinary(data) {\n var idx, tailbits,\n input = data.replace(/[\\r\\n=]/g, ''), // remove CR/LF & padding to simplify scan\n max = input.length,\n map = BASE64_MAP,\n bits = 0,\n result = [];\n\n // Collect by 6*4 bits (3 bytes)\n\n for (idx = 0; idx < max; idx++) {\n if ((idx % 4 === 0) && idx) {\n result.push((bits >> 16) & 0xFF);\n result.push((bits >> 8) & 0xFF);\n result.push(bits & 0xFF);\n }\n\n bits = (bits << 6) | map.indexOf(input.charAt(idx));\n }\n\n // Dump tail\n\n tailbits = (max % 4) * 6;\n\n if (tailbits === 0) {\n result.push((bits >> 16) & 0xFF);\n result.push((bits >> 8) & 0xFF);\n result.push(bits & 0xFF);\n } else if (tailbits === 18) {\n result.push((bits >> 10) & 0xFF);\n result.push((bits >> 2) & 0xFF);\n } else if (tailbits === 12) {\n result.push((bits >> 4) & 0xFF);\n }\n\n return new Uint8Array(result);\n}\n\nfunction representYamlBinary(object /*, style*/) {\n var result = '', bits = 0, idx, tail,\n max = object.length,\n map = BASE64_MAP;\n\n // Convert every three bytes to 4 ASCII characters.\n\n for (idx = 0; idx < max; idx++) {\n if ((idx % 3 === 0) && idx) {\n result += map[(bits >> 18) & 0x3F];\n result += map[(bits >> 12) & 0x3F];\n result += map[(bits >> 6) & 0x3F];\n result += map[bits & 0x3F];\n }\n\n bits = (bits << 8) + object[idx];\n }\n\n // Dump tail\n\n tail = max % 3;\n\n if (tail === 0) {\n result += map[(bits >> 18) & 0x3F];\n result += map[(bits >> 12) & 0x3F];\n result += map[(bits >> 6) & 0x3F];\n result += map[bits & 0x3F];\n } else if (tail === 2) {\n result += map[(bits >> 10) & 0x3F];\n result += map[(bits >> 4) & 0x3F];\n result += map[(bits << 2) & 0x3F];\n result += map[64];\n } else if (tail === 1) {\n result += map[(bits >> 2) & 0x3F];\n result += map[(bits << 4) & 0x3F];\n result += map[64];\n result += map[64];\n }\n\n return result;\n}\n\nfunction isBinary(obj) {\n return Object.prototype.toString.call(obj) === '[object Uint8Array]';\n}\n\nvar binary = new type('tag:yaml.org,2002:binary', {\n kind: 'scalar',\n resolve: resolveYamlBinary,\n construct: constructYamlBinary,\n predicate: isBinary,\n represent: representYamlBinary\n});\n\nvar _hasOwnProperty$3 = Object.prototype.hasOwnProperty;\nvar _toString$2 = Object.prototype.toString;\n\nfunction resolveYamlOmap(data) {\n if (data === null) return true;\n\n var objectKeys = [], index, length, pair, pairKey, pairHasKey,\n object = data;\n\n for (index = 0, length = object.length; index < length; index += 1) {\n pair = object[index];\n pairHasKey = false;\n\n if (_toString$2.call(pair) !== '[object Object]') return false;\n\n for (pairKey in pair) {\n if (_hasOwnProperty$3.call(pair, pairKey)) {\n if (!pairHasKey) pairHasKey = true;\n else return false;\n }\n }\n\n if (!pairHasKey) return false;\n\n if (objectKeys.indexOf(pairKey) === -1) objectKeys.push(pairKey);\n else return false;\n }\n\n return true;\n}\n\nfunction constructYamlOmap(data) {\n return data !== null ? data : [];\n}\n\nvar omap = new type('tag:yaml.org,2002:omap', {\n kind: 'sequence',\n resolve: resolveYamlOmap,\n construct: constructYamlOmap\n});\n\nvar _toString$1 = Object.prototype.toString;\n\nfunction resolveYamlPairs(data) {\n if (data === null) return true;\n\n var index, length, pair, keys, result,\n object = data;\n\n result = new Array(object.length);\n\n for (index = 0, length = object.length; index < length; index += 1) {\n pair = object[index];\n\n if (_toString$1.call(pair) !== '[object Object]') return false;\n\n keys = Object.keys(pair);\n\n if (keys.length !== 1) return false;\n\n result[index] = [ keys[0], pair[keys[0]] ];\n }\n\n return true;\n}\n\nfunction constructYamlPairs(data) {\n if (data === null) return [];\n\n var index, length, pair, keys, result,\n object = data;\n\n result = new Array(object.length);\n\n for (index = 0, length = object.length; index < length; index += 1) {\n pair = object[index];\n\n keys = Object.keys(pair);\n\n result[index] = [ keys[0], pair[keys[0]] ];\n }\n\n return result;\n}\n\nvar pairs = new type('tag:yaml.org,2002:pairs', {\n kind: 'sequence',\n resolve: resolveYamlPairs,\n construct: constructYamlPairs\n});\n\nvar _hasOwnProperty$2 = Object.prototype.hasOwnProperty;\n\nfunction resolveYamlSet(data) {\n if (data === null) return true;\n\n var key, object = data;\n\n for (key in object) {\n if (_hasOwnProperty$2.call(object, key)) {\n if (object[key] !== null) return false;\n }\n }\n\n return true;\n}\n\nfunction constructYamlSet(data) {\n return data !== null ? data : {};\n}\n\nvar set = new type('tag:yaml.org,2002:set', {\n kind: 'mapping',\n resolve: resolveYamlSet,\n construct: constructYamlSet\n});\n\nvar _default = core.extend({\n implicit: [\n timestamp,\n merge\n ],\n explicit: [\n binary,\n omap,\n pairs,\n set\n ]\n});\n\n/*eslint-disable max-len,no-use-before-define*/\n\n\n\n\n\n\n\nvar _hasOwnProperty$1 = Object.prototype.hasOwnProperty;\n\n\nvar CONTEXT_FLOW_IN = 1;\nvar CONTEXT_FLOW_OUT = 2;\nvar CONTEXT_BLOCK_IN = 3;\nvar CONTEXT_BLOCK_OUT = 4;\n\n\nvar CHOMPING_CLIP = 1;\nvar CHOMPING_STRIP = 2;\nvar CHOMPING_KEEP = 3;\n\n\nvar PATTERN_NON_PRINTABLE = /[\\x00-\\x08\\x0B\\x0C\\x0E-\\x1F\\x7F-\\x84\\x86-\\x9F\\uFFFE\\uFFFF]|[\\uD800-\\uDBFF](?![\\uDC00-\\uDFFF])|(?:[^\\uD800-\\uDBFF]|^)[\\uDC00-\\uDFFF]/;\nvar PATTERN_NON_ASCII_LINE_BREAKS = /[\\x85\\u2028\\u2029]/;\nvar PATTERN_FLOW_INDICATORS = /[,\\[\\]\\{\\}]/;\nvar PATTERN_TAG_HANDLE = /^(?:!|!!|![a-z\\-]+!)$/i;\nvar PATTERN_TAG_URI = /^(?:!|[^,\\[\\]\\{\\}])(?:%[0-9a-f]{2}|[0-9a-z\\-#;\\/\\?:@&=\\+\\$,_\\.!~\\*'\\(\\)\\[\\]])*$/i;\n\n\nfunction _class(obj) { return Object.prototype.toString.call(obj); }\n\nfunction is_EOL(c) {\n return (c === 0x0A/* LF */) || (c === 0x0D/* CR */);\n}\n\nfunction is_WHITE_SPACE(c) {\n return (c === 0x09/* Tab */) || (c === 0x20/* Space */);\n}\n\nfunction is_WS_OR_EOL(c) {\n return (c === 0x09/* Tab */) ||\n (c === 0x20/* Space */) ||\n (c === 0x0A/* LF */) ||\n (c === 0x0D/* CR */);\n}\n\nfunction is_FLOW_INDICATOR(c) {\n return c === 0x2C/* , */ ||\n c === 0x5B/* [ */ ||\n c === 0x5D/* ] */ ||\n c === 0x7B/* { */ ||\n c === 0x7D/* } */;\n}\n\nfunction fromHexCode(c) {\n var lc;\n\n if ((0x30/* 0 */ <= c) && (c <= 0x39/* 9 */)) {\n return c - 0x30;\n }\n\n /*eslint-disable no-bitwise*/\n lc = c | 0x20;\n\n if ((0x61/* a */ <= lc) && (lc <= 0x66/* f */)) {\n return lc - 0x61 + 10;\n }\n\n return -1;\n}\n\nfunction escapedHexLen(c) {\n if (c === 0x78/* x */) { return 2; }\n if (c === 0x75/* u */) { return 4; }\n if (c === 0x55/* U */) { return 8; }\n return 0;\n}\n\nfunction fromDecimalCode(c) {\n if ((0x30/* 0 */ <= c) && (c <= 0x39/* 9 */)) {\n return c - 0x30;\n }\n\n return -1;\n}\n\nfunction simpleEscapeSequence(c) {\n /* eslint-disable indent */\n return (c === 0x30/* 0 */) ? '\\x00' :\n (c === 0x61/* a */) ? '\\x07' :\n (c === 0x62/* b */) ? '\\x08' :\n (c === 0x74/* t */) ? '\\x09' :\n (c === 0x09/* Tab */) ? '\\x09' :\n (c === 0x6E/* n */) ? '\\x0A' :\n (c === 0x76/* v */) ? '\\x0B' :\n (c === 0x66/* f */) ? '\\x0C' :\n (c === 0x72/* r */) ? '\\x0D' :\n (c === 0x65/* e */) ? '\\x1B' :\n (c === 0x20/* Space */) ? ' ' :\n (c === 0x22/* \" */) ? '\\x22' :\n (c === 0x2F/* / */) ? '/' :\n (c === 0x5C/* \\ */) ? '\\x5C' :\n (c === 0x4E/* N */) ? '\\x85' :\n (c === 0x5F/* _ */) ? '\\xA0' :\n (c === 0x4C/* L */) ? '\\u2028' :\n (c === 0x50/* P */) ? '\\u2029' : '';\n}\n\nfunction charFromCodepoint(c) {\n if (c <= 0xFFFF) {\n return String.fromCharCode(c);\n }\n // Encode UTF-16 surrogate pair\n // https://en.wikipedia.org/wiki/UTF-16#Code_points_U.2B010000_to_U.2B10FFFF\n return String.fromCharCode(\n ((c - 0x010000) >> 10) + 0xD800,\n ((c - 0x010000) & 0x03FF) + 0xDC00\n );\n}\n\n// set a property of a literal object, while protecting against prototype pollution,\n// see https://github.com/nodeca/js-yaml/issues/164 for more details\nfunction setProperty(object, key, value) {\n // used for this specific key only because Object.defineProperty is slow\n if (key === '__proto__') {\n Object.defineProperty(object, key, {\n configurable: true,\n enumerable: true,\n writable: true,\n value: value\n });\n } else {\n object[key] = value;\n }\n}\n\nvar simpleEscapeCheck = new Array(256); // integer, for fast access\nvar simpleEscapeMap = new Array(256);\nfor (var i = 0; i < 256; i++) {\n simpleEscapeCheck[i] = simpleEscapeSequence(i) ? 1 : 0;\n simpleEscapeMap[i] = simpleEscapeSequence(i);\n}\n\n\nfunction State$1(input, options) {\n this.input = input;\n\n this.filename = options['filename'] || null;\n this.schema = options['schema'] || _default;\n this.onWarning = options['onWarning'] || null;\n // (Hidden) Remove? makes the loader to expect YAML 1.1 documents\n // if such documents have no explicit %YAML directive\n this.legacy = options['legacy'] || false;\n\n this.json = options['json'] || false;\n this.listener = options['listener'] || null;\n\n this.implicitTypes = this.schema.compiledImplicit;\n this.typeMap = this.schema.compiledTypeMap;\n\n this.length = input.length;\n this.position = 0;\n this.line = 0;\n this.lineStart = 0;\n this.lineIndent = 0;\n\n // position of first leading tab in the current line,\n // used to make sure there are no tabs in the indentation\n this.firstTabInLine = -1;\n\n this.documents = [];\n\n /*\n this.version;\n this.checkLineBreaks;\n this.tagMap;\n this.anchorMap;\n this.tag;\n this.anchor;\n this.kind;\n this.result;*/\n\n}\n\n\nfunction generateError(state, message) {\n var mark = {\n name: state.filename,\n buffer: state.input.slice(0, -1), // omit trailing \\0\n position: state.position,\n line: state.line,\n column: state.position - state.lineStart\n };\n\n mark.snippet = snippet(mark);\n\n return new exception(message, mark);\n}\n\nfunction throwError(state, message) {\n throw generateError(state, message);\n}\n\nfunction throwWarning(state, message) {\n if (state.onWarning) {\n state.onWarning.call(null, generateError(state, message));\n }\n}\n\n\nvar directiveHandlers = {\n\n YAML: function handleYamlDirective(state, name, args) {\n\n var match, major, minor;\n\n if (state.version !== null) {\n throwError(state, 'duplication of %YAML directive');\n }\n\n if (args.length !== 1) {\n throwError(state, 'YAML directive accepts exactly one argument');\n }\n\n match = /^([0-9]+)\\.([0-9]+)$/.exec(args[0]);\n\n if (match === null) {\n throwError(state, 'ill-formed argument of the YAML directive');\n }\n\n major = parseInt(match[1], 10);\n minor = parseInt(match[2], 10);\n\n if (major !== 1) {\n throwError(state, 'unacceptable YAML version of the document');\n }\n\n state.version = args[0];\n state.checkLineBreaks = (minor < 2);\n\n if (minor !== 1 && minor !== 2) {\n throwWarning(state, 'unsupported YAML version of the document');\n }\n },\n\n TAG: function handleTagDirective(state, name, args) {\n\n var handle, prefix;\n\n if (args.length !== 2) {\n throwError(state, 'TAG directive accepts exactly two arguments');\n }\n\n handle = args[0];\n prefix = args[1];\n\n if (!PATTERN_TAG_HANDLE.test(handle)) {\n throwError(state, 'ill-formed tag handle (first argument) of the TAG directive');\n }\n\n if (_hasOwnProperty$1.call(state.tagMap, handle)) {\n throwError(state, 'there is a previously declared suffix for \"' + handle + '\" tag handle');\n }\n\n if (!PATTERN_TAG_URI.test(prefix)) {\n throwError(state, 'ill-formed tag prefix (second argument) of the TAG directive');\n }\n\n try {\n prefix = decodeURIComponent(prefix);\n } catch (err) {\n throwError(state, 'tag prefix is malformed: ' + prefix);\n }\n\n state.tagMap[handle] = prefix;\n }\n};\n\n\nfunction captureSegment(state, start, end, checkJson) {\n var _position, _length, _character, _result;\n\n if (start < end) {\n _result = state.input.slice(start, end);\n\n if (checkJson) {\n for (_position = 0, _length = _result.length; _position < _length; _position += 1) {\n _character = _result.charCodeAt(_position);\n if (!(_character === 0x09 ||\n (0x20 <= _character && _character <= 0x10FFFF))) {\n throwError(state, 'expected valid JSON character');\n }\n }\n } else if (PATTERN_NON_PRINTABLE.test(_result)) {\n throwError(state, 'the stream contains non-printable characters');\n }\n\n state.result += _result;\n }\n}\n\nfunction mergeMappings(state, destination, source, overridableKeys) {\n var sourceKeys, key, index, quantity;\n\n if (!common.isObject(source)) {\n throwError(state, 'cannot merge mappings; the provided source object is unacceptable');\n }\n\n sourceKeys = Object.keys(source);\n\n for (index = 0, quantity = sourceKeys.length; index < quantity; index += 1) {\n key = sourceKeys[index];\n\n if (!_hasOwnProperty$1.call(destination, key)) {\n setProperty(destination, key, source[key]);\n overridableKeys[key] = true;\n }\n }\n}\n\nfunction storeMappingPair(state, _result, overridableKeys, keyTag, keyNode, valueNode,\n startLine, startLineStart, startPos) {\n\n var index, quantity;\n\n // The output is a plain object here, so keys can only be strings.\n // We need to convert keyNode to a string, but doing so can hang the process\n // (deeply nested arrays that explode exponentially using aliases).\n if (Array.isArray(keyNode)) {\n keyNode = Array.prototype.slice.call(keyNode);\n\n for (index = 0, quantity = keyNode.length; index < quantity; index += 1) {\n if (Array.isArray(keyNode[index])) {\n throwError(state, 'nested arrays are not supported inside keys');\n }\n\n if (typeof keyNode === 'object' && _class(keyNode[index]) === '[object Object]') {\n keyNode[index] = '[object Object]';\n }\n }\n }\n\n // Avoid code execution in load() via toString property\n // (still use its own toString for arrays, timestamps,\n // and whatever user schema extensions happen to have @@toStringTag)\n if (typeof keyNode === 'object' && _class(keyNode) === '[object Object]') {\n keyNode = '[object Object]';\n }\n\n\n keyNode = String(keyNode);\n\n if (_result === null) {\n _result = {};\n }\n\n if (keyTag === 'tag:yaml.org,2002:merge') {\n if (Array.isArray(valueNode)) {\n for (index = 0, quantity = valueNode.length; index < quantity; index += 1) {\n mergeMappings(state, _result, valueNode[index], overridableKeys);\n }\n } else {\n mergeMappings(state, _result, valueNode, overridableKeys);\n }\n } else {\n if (!state.json &&\n !_hasOwnProperty$1.call(overridableKeys, keyNode) &&\n _hasOwnProperty$1.call(_result, keyNode)) {\n state.line = startLine || state.line;\n state.lineStart = startLineStart || state.lineStart;\n state.position = startPos || state.position;\n throwError(state, 'duplicated mapping key');\n }\n\n setProperty(_result, keyNode, valueNode);\n delete overridableKeys[keyNode];\n }\n\n return _result;\n}\n\nfunction readLineBreak(state) {\n var ch;\n\n ch = state.input.charCodeAt(state.position);\n\n if (ch === 0x0A/* LF */) {\n state.position++;\n } else if (ch === 0x0D/* CR */) {\n state.position++;\n if (state.input.charCodeAt(state.position) === 0x0A/* LF */) {\n state.position++;\n }\n } else {\n throwError(state, 'a line break is expected');\n }\n\n state.line += 1;\n state.lineStart = state.position;\n state.firstTabInLine = -1;\n}\n\nfunction skipSeparationSpace(state, allowComments, checkIndent) {\n var lineBreaks = 0,\n ch = state.input.charCodeAt(state.position);\n\n while (ch !== 0) {\n while (is_WHITE_SPACE(ch)) {\n if (ch === 0x09/* Tab */ && state.firstTabInLine === -1) {\n state.firstTabInLine = state.position;\n }\n ch = state.input.charCodeAt(++state.position);\n }\n\n if (allowComments && ch === 0x23/* # */) {\n do {\n ch = state.input.charCodeAt(++state.position);\n } while (ch !== 0x0A/* LF */ && ch !== 0x0D/* CR */ && ch !== 0);\n }\n\n if (is_EOL(ch)) {\n readLineBreak(state);\n\n ch = state.input.charCodeAt(state.position);\n lineBreaks++;\n state.lineIndent = 0;\n\n while (ch === 0x20/* Space */) {\n state.lineIndent++;\n ch = state.input.charCodeAt(++state.position);\n }\n } else {\n break;\n }\n }\n\n if (checkIndent !== -1 && lineBreaks !== 0 && state.lineIndent < checkIndent) {\n throwWarning(state, 'deficient indentation');\n }\n\n return lineBreaks;\n}\n\nfunction testDocumentSeparator(state) {\n var _position = state.position,\n ch;\n\n ch = state.input.charCodeAt(_position);\n\n // Condition state.position === state.lineStart is tested\n // in parent on each call, for efficiency. No needs to test here again.\n if ((ch === 0x2D/* - */ || ch === 0x2E/* . */) &&\n ch === state.input.charCodeAt(_position + 1) &&\n ch === state.input.charCodeAt(_position + 2)) {\n\n _position += 3;\n\n ch = state.input.charCodeAt(_position);\n\n if (ch === 0 || is_WS_OR_EOL(ch)) {\n return true;\n }\n }\n\n return false;\n}\n\nfunction writeFoldedLines(state, count) {\n if (count === 1) {\n state.result += ' ';\n } else if (count > 1) {\n state.result += common.repeat('\\n', count - 1);\n }\n}\n\n\nfunction readPlainScalar(state, nodeIndent, withinFlowCollection) {\n var preceding,\n following,\n captureStart,\n captureEnd,\n hasPendingContent,\n _line,\n _lineStart,\n _lineIndent,\n _kind = state.kind,\n _result = state.result,\n ch;\n\n ch = state.input.charCodeAt(state.position);\n\n if (is_WS_OR_EOL(ch) ||\n is_FLOW_INDICATOR(ch) ||\n ch === 0x23/* # */ ||\n ch === 0x26/* & */ ||\n ch === 0x2A/* * */ ||\n ch === 0x21/* ! */ ||\n ch === 0x7C/* | */ ||\n ch === 0x3E/* > */ ||\n ch === 0x27/* ' */ ||\n ch === 0x22/* \" */ ||\n ch === 0x25/* % */ ||\n ch === 0x40/* @ */ ||\n ch === 0x60/* ` */) {\n return false;\n }\n\n if (ch === 0x3F/* ? */ || ch === 0x2D/* - */) {\n following = state.input.charCodeAt(state.position + 1);\n\n if (is_WS_OR_EOL(following) ||\n withinFlowCollection && is_FLOW_INDICATOR(following)) {\n return false;\n }\n }\n\n state.kind = 'scalar';\n state.result = '';\n captureStart = captureEnd = state.position;\n hasPendingContent = false;\n\n while (ch !== 0) {\n if (ch === 0x3A/* : */) {\n following = state.input.charCodeAt(state.position + 1);\n\n if (is_WS_OR_EOL(following) ||\n withinFlowCollection && is_FLOW_INDICATOR(following)) {\n break;\n }\n\n } else if (ch === 0x23/* # */) {\n preceding = state.input.charCodeAt(state.position - 1);\n\n if (is_WS_OR_EOL(preceding)) {\n break;\n }\n\n } else if ((state.position === state.lineStart && testDocumentSeparator(state)) ||\n withinFlowCollection && is_FLOW_INDICATOR(ch)) {\n break;\n\n } else if (is_EOL(ch)) {\n _line = state.line;\n _lineStart = state.lineStart;\n _lineIndent = state.lineIndent;\n skipSeparationSpace(state, false, -1);\n\n if (state.lineIndent >= nodeIndent) {\n hasPendingContent = true;\n ch = state.input.charCodeAt(state.position);\n continue;\n } else {\n state.position = captureEnd;\n state.line = _line;\n state.lineStart = _lineStart;\n state.lineIndent = _lineIndent;\n break;\n }\n }\n\n if (hasPendingContent) {\n captureSegment(state, captureStart, captureEnd, false);\n writeFoldedLines(state, state.line - _line);\n captureStart = captureEnd = state.position;\n hasPendingContent = false;\n }\n\n if (!is_WHITE_SPACE(ch)) {\n captureEnd = state.position + 1;\n }\n\n ch = state.input.charCodeAt(++state.position);\n }\n\n captureSegment(state, captureStart, captureEnd, false);\n\n if (state.result) {\n return true;\n }\n\n state.kind = _kind;\n state.result = _result;\n return false;\n}\n\nfunction readSingleQuotedScalar(state, nodeIndent) {\n var ch,\n captureStart, captureEnd;\n\n ch = state.input.charCodeAt(state.position);\n\n if (ch !== 0x27/* ' */) {\n return false;\n }\n\n state.kind = 'scalar';\n state.result = '';\n state.position++;\n captureStart = captureEnd = state.position;\n\n while ((ch = state.input.charCodeAt(state.position)) !== 0) {\n if (ch === 0x27/* ' */) {\n captureSegment(state, captureStart, state.position, true);\n ch = state.input.charCodeAt(++state.position);\n\n if (ch === 0x27/* ' */) {\n captureStart = state.position;\n state.position++;\n captureEnd = state.position;\n } else {\n return true;\n }\n\n } else if (is_EOL(ch)) {\n captureSegment(state, captureStart, captureEnd, true);\n writeFoldedLines(state, skipSeparationSpace(state, false, nodeIndent));\n captureStart = captureEnd = state.position;\n\n } else if (state.position === state.lineStart && testDocumentSeparator(state)) {\n throwError(state, 'unexpected end of the document within a single quoted scalar');\n\n } else {\n state.position++;\n captureEnd = state.position;\n }\n }\n\n throwError(state, 'unexpected end of the stream within a single quoted scalar');\n}\n\nfunction readDoubleQuotedScalar(state, nodeIndent) {\n var captureStart,\n captureEnd,\n hexLength,\n hexResult,\n tmp,\n ch;\n\n ch = state.input.charCodeAt(state.position);\n\n if (ch !== 0x22/* \" */) {\n return false;\n }\n\n state.kind = 'scalar';\n state.result = '';\n state.position++;\n captureStart = captureEnd = state.position;\n\n while ((ch = state.input.charCodeAt(state.position)) !== 0) {\n if (ch === 0x22/* \" */) {\n captureSegment(state, captureStart, state.position, true);\n state.position++;\n return true;\n\n } else if (ch === 0x5C/* \\ */) {\n captureSegment(state, captureStart, state.position, true);\n ch = state.input.charCodeAt(++state.position);\n\n if (is_EOL(ch)) {\n skipSeparationSpace(state, false, nodeIndent);\n\n // TODO: rework to inline fn with no type cast?\n } else if (ch < 256 && simpleEscapeCheck[ch]) {\n state.result += simpleEscapeMap[ch];\n state.position++;\n\n } else if ((tmp = escapedHexLen(ch)) > 0) {\n hexLength = tmp;\n hexResult = 0;\n\n for (; hexLength > 0; hexLength--) {\n ch = state.input.charCodeAt(++state.position);\n\n if ((tmp = fromHexCode(ch)) >= 0) {\n hexResult = (hexResult << 4) + tmp;\n\n } else {\n throwError(state, 'expected hexadecimal character');\n }\n }\n\n state.result += charFromCodepoint(hexResult);\n\n state.position++;\n\n } else {\n throwError(state, 'unknown escape sequence');\n }\n\n captureStart = captureEnd = state.position;\n\n } else if (is_EOL(ch)) {\n captureSegment(state, captureStart, captureEnd, true);\n writeFoldedLines(state, skipSeparationSpace(state, false, nodeIndent));\n captureStart = captureEnd = state.position;\n\n } else if (state.position === state.lineStart && testDocumentSeparator(state)) {\n throwError(state, 'unexpected end of the document within a double quoted scalar');\n\n } else {\n state.position++;\n captureEnd = state.position;\n }\n }\n\n throwError(state, 'unexpected end of the stream within a double quoted scalar');\n}\n\nfunction readFlowCollection(state, nodeIndent) {\n var readNext = true,\n _line,\n _lineStart,\n _pos,\n _tag = state.tag,\n _result,\n _anchor = state.anchor,\n following,\n terminator,\n isPair,\n isExplicitPair,\n isMapping,\n overridableKeys = Object.create(null),\n keyNode,\n keyTag,\n valueNode,\n ch;\n\n ch = state.input.charCodeAt(state.position);\n\n if (ch === 0x5B/* [ */) {\n terminator = 0x5D;/* ] */\n isMapping = false;\n _result = [];\n } else if (ch === 0x7B/* { */) {\n terminator = 0x7D;/* } */\n isMapping = true;\n _result = {};\n } else {\n return false;\n }\n\n if (state.anchor !== null) {\n state.anchorMap[state.anchor] = _result;\n }\n\n ch = state.input.charCodeAt(++state.position);\n\n while (ch !== 0) {\n skipSeparationSpace(state, true, nodeIndent);\n\n ch = state.input.charCodeAt(state.position);\n\n if (ch === terminator) {\n state.position++;\n state.tag = _tag;\n state.anchor = _anchor;\n state.kind = isMapping ? 'mapping' : 'sequence';\n state.result = _result;\n return true;\n } else if (!readNext) {\n throwError(state, 'missed comma between flow collection entries');\n } else if (ch === 0x2C/* , */) {\n // \"flow collection entries can never be completely empty\", as per YAML 1.2, section 7.4\n throwError(state, \"expected the node content, but found ','\");\n }\n\n keyTag = keyNode = valueNode = null;\n isPair = isExplicitPair = false;\n\n if (ch === 0x3F/* ? */) {\n following = state.input.charCodeAt(state.position + 1);\n\n if (is_WS_OR_EOL(following)) {\n isPair = isExplicitPair = true;\n state.position++;\n skipSeparationSpace(state, true, nodeIndent);\n }\n }\n\n _line = state.line; // Save the current line.\n _lineStart = state.lineStart;\n _pos = state.position;\n composeNode(state, nodeIndent, CONTEXT_FLOW_IN, false, true);\n keyTag = state.tag;\n keyNode = state.result;\n skipSeparationSpace(state, true, nodeIndent);\n\n ch = state.input.charCodeAt(state.position);\n\n if ((isExplicitPair || state.line === _line) && ch === 0x3A/* : */) {\n isPair = true;\n ch = state.input.charCodeAt(++state.position);\n skipSeparationSpace(state, true, nodeIndent);\n composeNode(state, nodeIndent, CONTEXT_FLOW_IN, false, true);\n valueNode = state.result;\n }\n\n if (isMapping) {\n storeMappingPair(state, _result, overridableKeys, keyTag, keyNode, valueNode, _line, _lineStart, _pos);\n } else if (isPair) {\n _result.push(storeMappingPair(state, null, overridableKeys, keyTag, keyNode, valueNode, _line, _lineStart, _pos));\n } else {\n _result.push(keyNode);\n }\n\n skipSeparationSpace(state, true, nodeIndent);\n\n ch = state.input.charCodeAt(state.position);\n\n if (ch === 0x2C/* , */) {\n readNext = true;\n ch = state.input.charCodeAt(++state.position);\n } else {\n readNext = false;\n }\n }\n\n throwError(state, 'unexpected end of the stream within a flow collection');\n}\n\nfunction readBlockScalar(state, nodeIndent) {\n var captureStart,\n folding,\n chomping = CHOMPING_CLIP,\n didReadContent = false,\n detectedIndent = false,\n textIndent = nodeIndent,\n emptyLines = 0,\n atMoreIndented = false,\n tmp,\n ch;\n\n ch = state.input.charCodeAt(state.position);\n\n if (ch === 0x7C/* | */) {\n folding = false;\n } else if (ch === 0x3E/* > */) {\n folding = true;\n } else {\n return false;\n }\n\n state.kind = 'scalar';\n state.result = '';\n\n while (ch !== 0) {\n ch = state.input.charCodeAt(++state.position);\n\n if (ch === 0x2B/* + */ || ch === 0x2D/* - */) {\n if (CHOMPING_CLIP === chomping) {\n chomping = (ch === 0x2B/* + */) ? CHOMPING_KEEP : CHOMPING_STRIP;\n } else {\n throwError(state, 'repeat of a chomping mode identifier');\n }\n\n } else if ((tmp = fromDecimalCode(ch)) >= 0) {\n if (tmp === 0) {\n throwError(state, 'bad explicit indentation width of a block scalar; it cannot be less than one');\n } else if (!detectedIndent) {\n textIndent = nodeIndent + tmp - 1;\n detectedIndent = true;\n } else {\n throwError(state, 'repeat of an indentation width identifier');\n }\n\n } else {\n break;\n }\n }\n\n if (is_WHITE_SPACE(ch)) {\n do { ch = state.input.charCodeAt(++state.position); }\n while (is_WHITE_SPACE(ch));\n\n if (ch === 0x23/* # */) {\n do { ch = state.input.charCodeAt(++state.position); }\n while (!is_EOL(ch) && (ch !== 0));\n }\n }\n\n while (ch !== 0) {\n readLineBreak(state);\n state.lineIndent = 0;\n\n ch = state.input.charCodeAt(state.position);\n\n while ((!detectedIndent || state.lineIndent < textIndent) &&\n (ch === 0x20/* Space */)) {\n state.lineIndent++;\n ch = state.input.charCodeAt(++state.position);\n }\n\n if (!detectedIndent && state.lineIndent > textIndent) {\n textIndent = state.lineIndent;\n }\n\n if (is_EOL(ch)) {\n emptyLines++;\n continue;\n }\n\n // End of the scalar.\n if (state.lineIndent < textIndent) {\n\n // Perform the chomping.\n if (chomping === CHOMPING_KEEP) {\n state.result += common.repeat('\\n', didReadContent ? 1 + emptyLines : emptyLines);\n } else if (chomping === CHOMPING_CLIP) {\n if (didReadContent) { // i.e. only if the scalar is not empty.\n state.result += '\\n';\n }\n }\n\n // Break this `while` cycle and go to the funciton's epilogue.\n break;\n }\n\n // Folded style: use fancy rules to handle line breaks.\n if (folding) {\n\n // Lines starting with white space characters (more-indented lines) are not folded.\n if (is_WHITE_SPACE(ch)) {\n atMoreIndented = true;\n // except for the first content line (cf. Example 8.1)\n state.result += common.repeat('\\n', didReadContent ? 1 + emptyLines : emptyLines);\n\n // End of more-indented block.\n } else if (atMoreIndented) {\n atMoreIndented = false;\n state.result += common.repeat('\\n', emptyLines + 1);\n\n // Just one line break - perceive as the same line.\n } else if (emptyLines === 0) {\n if (didReadContent) { // i.e. only if we have already read some scalar content.\n state.result += ' ';\n }\n\n // Several line breaks - perceive as different lines.\n } else {\n state.result += common.repeat('\\n', emptyLines);\n }\n\n // Literal style: just add exact number of line breaks between content lines.\n } else {\n // Keep all line breaks except the header line break.\n state.result += common.repeat('\\n', didReadContent ? 1 + emptyLines : emptyLines);\n }\n\n didReadContent = true;\n detectedIndent = true;\n emptyLines = 0;\n captureStart = state.position;\n\n while (!is_EOL(ch) && (ch !== 0)) {\n ch = state.input.charCodeAt(++state.position);\n }\n\n captureSegment(state, captureStart, state.position, false);\n }\n\n return true;\n}\n\nfunction readBlockSequence(state, nodeIndent) {\n var _line,\n _tag = state.tag,\n _anchor = state.anchor,\n _result = [],\n following,\n detected = false,\n ch;\n\n // there is a leading tab before this token, so it can't be a block sequence/mapping;\n // it can still be flow sequence/mapping or a scalar\n if (state.firstTabInLine !== -1) return false;\n\n if (state.anchor !== null) {\n state.anchorMap[state.anchor] = _result;\n }\n\n ch = state.input.charCodeAt(state.position);\n\n while (ch !== 0) {\n if (state.firstTabInLine !== -1) {\n state.position = state.firstTabInLine;\n throwError(state, 'tab characters must not be used in indentation');\n }\n\n if (ch !== 0x2D/* - */) {\n break;\n }\n\n following = state.input.charCodeAt(state.position + 1);\n\n if (!is_WS_OR_EOL(following)) {\n break;\n }\n\n detected = true;\n state.position++;\n\n if (skipSeparationSpace(state, true, -1)) {\n if (state.lineIndent <= nodeIndent) {\n _result.push(null);\n ch = state.input.charCodeAt(state.position);\n continue;\n }\n }\n\n _line = state.line;\n composeNode(state, nodeIndent, CONTEXT_BLOCK_IN, false, true);\n _result.push(state.result);\n skipSeparationSpace(state, true, -1);\n\n ch = state.input.charCodeAt(state.position);\n\n if ((state.line === _line || state.lineIndent > nodeIndent) && (ch !== 0)) {\n throwError(state, 'bad indentation of a sequence entry');\n } else if (state.lineIndent < nodeIndent) {\n break;\n }\n }\n\n if (detected) {\n state.tag = _tag;\n state.anchor = _anchor;\n state.kind = 'sequence';\n state.result = _result;\n return true;\n }\n return false;\n}\n\nfunction readBlockMapping(state, nodeIndent, flowIndent) {\n var following,\n allowCompact,\n _line,\n _keyLine,\n _keyLineStart,\n _keyPos,\n _tag = state.tag,\n _anchor = state.anchor,\n _result = {},\n overridableKeys = Object.create(null),\n keyTag = null,\n keyNode = null,\n valueNode = null,\n atExplicitKey = false,\n detected = false,\n ch;\n\n // there is a leading tab before this token, so it can't be a block sequence/mapping;\n // it can still be flow sequence/mapping or a scalar\n if (state.firstTabInLine !== -1) return false;\n\n if (state.anchor !== null) {\n state.anchorMap[state.anchor] = _result;\n }\n\n ch = state.input.charCodeAt(state.position);\n\n while (ch !== 0) {\n if (!atExplicitKey && state.firstTabInLine !== -1) {\n state.position = state.firstTabInLine;\n throwError(state, 'tab characters must not be used in indentation');\n }\n\n following = state.input.charCodeAt(state.position + 1);\n _line = state.line; // Save the current line.\n\n //\n // Explicit notation case. There are two separate blocks:\n // first for the key (denoted by \"?\") and second for the value (denoted by \":\")\n //\n if ((ch === 0x3F/* ? */ || ch === 0x3A/* : */) && is_WS_OR_EOL(following)) {\n\n if (ch === 0x3F/* ? */) {\n if (atExplicitKey) {\n storeMappingPair(state, _result, overridableKeys, keyTag, keyNode, null, _keyLine, _keyLineStart, _keyPos);\n keyTag = keyNode = valueNode = null;\n }\n\n detected = true;\n atExplicitKey = true;\n allowCompact = true;\n\n } else if (atExplicitKey) {\n // i.e. 0x3A/* : */ === character after the explicit key.\n atExplicitKey = false;\n allowCompact = true;\n\n } else {\n throwError(state, 'incomplete explicit mapping pair; a key node is missed; or followed by a non-tabulated empty line');\n }\n\n state.position += 1;\n ch = following;\n\n //\n // Implicit notation case. Flow-style node as the key first, then \":\", and the value.\n //\n } else {\n _keyLine = state.line;\n _keyLineStart = state.lineStart;\n _keyPos = state.position;\n\n if (!composeNode(state, flowIndent, CONTEXT_FLOW_OUT, false, true)) {\n // Neither implicit nor explicit notation.\n // Reading is done. Go to the epilogue.\n break;\n }\n\n if (state.line === _line) {\n ch = state.input.charCodeAt(state.position);\n\n while (is_WHITE_SPACE(ch)) {\n ch = state.input.charCodeAt(++state.position);\n }\n\n if (ch === 0x3A/* : */) {\n ch = state.input.charCodeAt(++state.position);\n\n if (!is_WS_OR_EOL(ch)) {\n throwError(state, 'a whitespace character is expected after the key-value separator within a block mapping');\n }\n\n if (atExplicitKey) {\n storeMappingPair(state, _result, overridableKeys, keyTag, keyNode, null, _keyLine, _keyLineStart, _keyPos);\n keyTag = keyNode = valueNode = null;\n }\n\n detected = true;\n atExplicitKey = false;\n allowCompact = false;\n keyTag = state.tag;\n keyNode = state.result;\n\n } else if (detected) {\n throwError(state, 'can not read an implicit mapping pair; a colon is missed');\n\n } else {\n state.tag = _tag;\n state.anchor = _anchor;\n return true; // Keep the result of `composeNode`.\n }\n\n } else if (detected) {\n throwError(state, 'can not read a block mapping entry; a multiline key may not be an implicit key');\n\n } else {\n state.tag = _tag;\n state.anchor = _anchor;\n return true; // Keep the result of `composeNode`.\n }\n }\n\n //\n // Common reading code for both explicit and implicit notations.\n //\n if (state.line === _line || state.lineIndent > nodeIndent) {\n if (atExplicitKey) {\n _keyLine = state.line;\n _keyLineStart = state.lineStart;\n _keyPos = state.position;\n }\n\n if (composeNode(state, nodeIndent, CONTEXT_BLOCK_OUT, true, allowCompact)) {\n if (atExplicitKey) {\n keyNode = state.result;\n } else {\n valueNode = state.result;\n }\n }\n\n if (!atExplicitKey) {\n storeMappingPair(state, _result, overridableKeys, keyTag, keyNode, valueNode, _keyLine, _keyLineStart, _keyPos);\n keyTag = keyNode = valueNode = null;\n }\n\n skipSeparationSpace(state, true, -1);\n ch = state.input.charCodeAt(state.position);\n }\n\n if ((state.line === _line || state.lineIndent > nodeIndent) && (ch !== 0)) {\n throwError(state, 'bad indentation of a mapping entry');\n } else if (state.lineIndent < nodeIndent) {\n break;\n }\n }\n\n //\n // Epilogue.\n //\n\n // Special case: last mapping's node contains only the key in explicit notation.\n if (atExplicitKey) {\n storeMappingPair(state, _result, overridableKeys, keyTag, keyNode, null, _keyLine, _keyLineStart, _keyPos);\n }\n\n // Expose the resulting mapping.\n if (detected) {\n state.tag = _tag;\n state.anchor = _anchor;\n state.kind = 'mapping';\n state.result = _result;\n }\n\n return detected;\n}\n\nfunction readTagProperty(state) {\n var _position,\n isVerbatim = false,\n isNamed = false,\n tagHandle,\n tagName,\n ch;\n\n ch = state.input.charCodeAt(state.position);\n\n if (ch !== 0x21/* ! */) return false;\n\n if (state.tag !== null) {\n throwError(state, 'duplication of a tag property');\n }\n\n ch = state.input.charCodeAt(++state.position);\n\n if (ch === 0x3C/* < */) {\n isVerbatim = true;\n ch = state.input.charCodeAt(++state.position);\n\n } else if (ch === 0x21/* ! */) {\n isNamed = true;\n tagHandle = '!!';\n ch = state.input.charCodeAt(++state.position);\n\n } else {\n tagHandle = '!';\n }\n\n _position = state.position;\n\n if (isVerbatim) {\n do { ch = state.input.charCodeAt(++state.position); }\n while (ch !== 0 && ch !== 0x3E/* > */);\n\n if (state.position < state.length) {\n tagName = state.input.slice(_position, state.position);\n ch = state.input.charCodeAt(++state.position);\n } else {\n throwError(state, 'unexpected end of the stream within a verbatim tag');\n }\n } else {\n while (ch !== 0 && !is_WS_OR_EOL(ch)) {\n\n if (ch === 0x21/* ! */) {\n if (!isNamed) {\n tagHandle = state.input.slice(_position - 1, state.position + 1);\n\n if (!PATTERN_TAG_HANDLE.test(tagHandle)) {\n throwError(state, 'named tag handle cannot contain such characters');\n }\n\n isNamed = true;\n _position = state.position + 1;\n } else {\n throwError(state, 'tag suffix cannot contain exclamation marks');\n }\n }\n\n ch = state.input.charCodeAt(++state.position);\n }\n\n tagName = state.input.slice(_position, state.position);\n\n if (PATTERN_FLOW_INDICATORS.test(tagName)) {\n throwError(state, 'tag suffix cannot contain flow indicator characters');\n }\n }\n\n if (tagName && !PATTERN_TAG_URI.test(tagName)) {\n throwError(state, 'tag name cannot contain such characters: ' + tagName);\n }\n\n try {\n tagName = decodeURIComponent(tagName);\n } catch (err) {\n throwError(state, 'tag name is malformed: ' + tagName);\n }\n\n if (isVerbatim) {\n state.tag = tagName;\n\n } else if (_hasOwnProperty$1.call(state.tagMap, tagHandle)) {\n state.tag = state.tagMap[tagHandle] + tagName;\n\n } else if (tagHandle === '!') {\n state.tag = '!' + tagName;\n\n } else if (tagHandle === '!!') {\n state.tag = 'tag:yaml.org,2002:' + tagName;\n\n } else {\n throwError(state, 'undeclared tag handle \"' + tagHandle + '\"');\n }\n\n return true;\n}\n\nfunction readAnchorProperty(state) {\n var _position,\n ch;\n\n ch = state.input.charCodeAt(state.position);\n\n if (ch !== 0x26/* & */) return false;\n\n if (state.anchor !== null) {\n throwError(state, 'duplication of an anchor property');\n }\n\n ch = state.input.charCodeAt(++state.position);\n _position = state.position;\n\n while (ch !== 0 && !is_WS_OR_EOL(ch) && !is_FLOW_INDICATOR(ch)) {\n ch = state.input.charCodeAt(++state.position);\n }\n\n if (state.position === _position) {\n throwError(state, 'name of an anchor node must contain at least one character');\n }\n\n state.anchor = state.input.slice(_position, state.position);\n return true;\n}\n\nfunction readAlias(state) {\n var _position, alias,\n ch;\n\n ch = state.input.charCodeAt(state.position);\n\n if (ch !== 0x2A/* * */) return false;\n\n ch = state.input.charCodeAt(++state.position);\n _position = state.position;\n\n while (ch !== 0 && !is_WS_OR_EOL(ch) && !is_FLOW_INDICATOR(ch)) {\n ch = state.input.charCodeAt(++state.position);\n }\n\n if (state.position === _position) {\n throwError(state, 'name of an alias node must contain at least one character');\n }\n\n alias = state.input.slice(_position, state.position);\n\n if (!_hasOwnProperty$1.call(state.anchorMap, alias)) {\n throwError(state, 'unidentified alias \"' + alias + '\"');\n }\n\n state.result = state.anchorMap[alias];\n skipSeparationSpace(state, true, -1);\n return true;\n}\n\nfunction composeNode(state, parentIndent, nodeContext, allowToSeek, allowCompact) {\n var allowBlockStyles,\n allowBlockScalars,\n allowBlockCollections,\n indentStatus = 1, // 1: this>parent, 0: this=parent, -1: this<parent\n atNewLine = false,\n hasContent = false,\n typeIndex,\n typeQuantity,\n typeList,\n type,\n flowIndent,\n blockIndent;\n\n if (state.listener !== null) {\n state.listener('open', state);\n }\n\n state.tag = null;\n state.anchor = null;\n state.kind = null;\n state.result = null;\n\n allowBlockStyles = allowBlockScalars = allowBlockCollections =\n CONTEXT_BLOCK_OUT === nodeContext ||\n CONTEXT_BLOCK_IN === nodeContext;\n\n if (allowToSeek) {\n if (skipSeparationSpace(state, true, -1)) {\n atNewLine = true;\n\n if (state.lineIndent > parentIndent) {\n indentStatus = 1;\n } else if (state.lineIndent === parentIndent) {\n indentStatus = 0;\n } else if (state.lineIndent < parentIndent) {\n indentStatus = -1;\n }\n }\n }\n\n if (indentStatus === 1) {\n while (readTagProperty(state) || readAnchorProperty(state)) {\n if (skipSeparationSpace(state, true, -1)) {\n atNewLine = true;\n allowBlockCollections = allowBlockStyles;\n\n if (state.lineIndent > parentIndent) {\n indentStatus = 1;\n } else if (state.lineIndent === parentIndent) {\n indentStatus = 0;\n } else if (state.lineIndent < parentIndent) {\n indentStatus = -1;\n }\n } else {\n allowBlockCollections = false;\n }\n }\n }\n\n if (allowBlockCollections) {\n allowBlockCollections = atNewLine || allowCompact;\n }\n\n if (indentStatus === 1 || CONTEXT_BLOCK_OUT === nodeContext) {\n if (CONTEXT_FLOW_IN === nodeContext || CONTEXT_FLOW_OUT === nodeContext) {\n flowIndent = parentIndent;\n } else {\n flowIndent = parentIndent + 1;\n }\n\n blockIndent = state.position - state.lineStart;\n\n if (indentStatus === 1) {\n if (allowBlockCollections &&\n (readBlockSequence(state, blockIndent) ||\n readBlockMapping(state, blockIndent, flowIndent)) ||\n readFlowCollection(state, flowIndent)) {\n hasContent = true;\n } else {\n if ((allowBlockScalars && readBlockScalar(state, flowIndent)) ||\n readSingleQuotedScalar(state, flowIndent) ||\n readDoubleQuotedScalar(state, flowIndent)) {\n hasContent = true;\n\n } else if (readAlias(state)) {\n hasContent = true;\n\n if (state.tag !== null || state.anchor !== null) {\n throwError(state, 'alias node should not have any properties');\n }\n\n } else if (readPlainScalar(state, flowIndent, CONTEXT_FLOW_IN === nodeContext)) {\n hasContent = true;\n\n if (state.tag === null) {\n state.tag = '?';\n }\n }\n\n if (state.anchor !== null) {\n state.anchorMap[state.anchor] = state.result;\n }\n }\n } else if (indentStatus === 0) {\n // Special case: block sequences are allowed to have same indentation level as the parent.\n // http://www.yaml.org/spec/1.2/spec.html#id2799784\n hasContent = allowBlockCollections && readBlockSequence(state, blockIndent);\n }\n }\n\n if (state.tag === null) {\n if (state.anchor !== null) {\n state.anchorMap[state.anchor] = state.result;\n }\n\n } else if (state.tag === '?') {\n // Implicit resolving is not allowed for non-scalar types, and '?'\n // non-specific tag is only automatically assigned to plain scalars.\n //\n // We only need to check kind conformity in case user explicitly assigns '?'\n // tag, for example like this: \"!<?> [0]\"\n //\n if (state.result !== null && state.kind !== 'scalar') {\n throwError(state, 'unacceptable node kind for !<?> tag; it should be \"scalar\", not \"' + state.kind + '\"');\n }\n\n for (typeIndex = 0, typeQuantity = state.implicitTypes.length; typeIndex < typeQuantity; typeIndex += 1) {\n type = state.implicitTypes[typeIndex];\n\n if (type.resolve(state.result)) { // `state.result` updated in resolver if matched\n state.result = type.construct(state.result);\n state.tag = type.tag;\n if (state.anchor !== null) {\n state.anchorMap[state.anchor] = state.result;\n }\n break;\n }\n }\n } else if (state.tag !== '!') {\n if (_hasOwnProperty$1.call(state.typeMap[state.kind || 'fallback'], state.tag)) {\n type = state.typeMap[state.kind || 'fallback'][state.tag];\n } else {\n // looking for multi type\n type = null;\n typeList = state.typeMap.multi[state.kind || 'fallback'];\n\n for (typeIndex = 0, typeQuantity = typeList.length; typeIndex < typeQuantity; typeIndex += 1) {\n if (state.tag.slice(0, typeList[typeIndex].tag.length) === typeList[typeIndex].tag) {\n type = typeList[typeIndex];\n break;\n }\n }\n }\n\n if (!type) {\n throwError(state, 'unknown tag !<' + state.tag + '>');\n }\n\n if (state.result !== null && type.kind !== state.kind) {\n throwError(state, 'unacceptable node kind for !<' + state.tag + '> tag; it should be \"' + type.kind + '\", not \"' + state.kind + '\"');\n }\n\n if (!type.resolve(state.result, state.tag)) { // `state.result` updated in resolver if matched\n throwError(state, 'cannot resolve a node with !<' + state.tag + '> explicit tag');\n } else {\n state.result = type.construct(state.result, state.tag);\n if (state.anchor !== null) {\n state.anchorMap[state.anchor] = state.result;\n }\n }\n }\n\n if (state.listener !== null) {\n state.listener('close', state);\n }\n return state.tag !== null || state.anchor !== null || hasContent;\n}\n\nfunction readDocument(state) {\n var documentStart = state.position,\n _position,\n directiveName,\n directiveArgs,\n hasDirectives = false,\n ch;\n\n state.version = null;\n state.checkLineBreaks = state.legacy;\n state.tagMap = Object.create(null);\n state.anchorMap = Object.create(null);\n\n while ((ch = state.input.charCodeAt(state.position)) !== 0) {\n skipSeparationSpace(state, true, -1);\n\n ch = state.input.charCodeAt(state.position);\n\n if (state.lineIndent > 0 || ch !== 0x25/* % */) {\n break;\n }\n\n hasDirectives = true;\n ch = state.input.charCodeAt(++state.position);\n _position = state.position;\n\n while (ch !== 0 && !is_WS_OR_EOL(ch)) {\n ch = state.input.charCodeAt(++state.position);\n }\n\n directiveName = state.input.slice(_position, state.position);\n directiveArgs = [];\n\n if (directiveName.length < 1) {\n throwError(state, 'directive name must not be less than one character in length');\n }\n\n while (ch !== 0) {\n while (is_WHITE_SPACE(ch)) {\n ch = state.input.charCodeAt(++state.position);\n }\n\n if (ch === 0x23/* # */) {\n do { ch = state.input.charCodeAt(++state.position); }\n while (ch !== 0 && !is_EOL(ch));\n break;\n }\n\n if (is_EOL(ch)) break;\n\n _position = state.position;\n\n while (ch !== 0 && !is_WS_OR_EOL(ch)) {\n ch = state.input.charCodeAt(++state.position);\n }\n\n directiveArgs.push(state.input.slice(_position, state.position));\n }\n\n if (ch !== 0) readLineBreak(state);\n\n if (_hasOwnProperty$1.call(directiveHandlers, directiveName)) {\n directiveHandlers[directiveName](state, directiveName, directiveArgs);\n } else {\n throwWarning(state, 'unknown document directive \"' + directiveName + '\"');\n }\n }\n\n skipSeparationSpace(state, true, -1);\n\n if (state.lineIndent === 0 &&\n state.input.charCodeAt(state.position) === 0x2D/* - */ &&\n state.input.charCodeAt(state.position + 1) === 0x2D/* - */ &&\n state.input.charCodeAt(state.position + 2) === 0x2D/* - */) {\n state.position += 3;\n skipSeparationSpace(state, true, -1);\n\n } else if (hasDirectives) {\n throwError(state, 'directives end mark is expected');\n }\n\n composeNode(state, state.lineIndent - 1, CONTEXT_BLOCK_OUT, false, true);\n skipSeparationSpace(state, true, -1);\n\n if (state.checkLineBreaks &&\n PATTERN_NON_ASCII_LINE_BREAKS.test(state.input.slice(documentStart, state.position))) {\n throwWarning(state, 'non-ASCII line breaks are interpreted as content');\n }\n\n state.documents.push(state.result);\n\n if (state.position === state.lineStart && testDocumentSeparator(state)) {\n\n if (state.input.charCodeAt(state.position) === 0x2E/* . */) {\n state.position += 3;\n skipSeparationSpace(state, true, -1);\n }\n return;\n }\n\n if (state.position < (state.length - 1)) {\n throwError(state, 'end of the stream or a document separator is expected');\n } else {\n return;\n }\n}\n\n\nfunction loadDocuments(input, options) {\n input = String(input);\n options = options || {};\n\n if (input.length !== 0) {\n\n // Add tailing `\\n` if not exists\n if (input.charCodeAt(input.length - 1) !== 0x0A/* LF */ &&\n input.charCodeAt(input.length - 1) !== 0x0D/* CR */) {\n input += '\\n';\n }\n\n // Strip BOM\n if (input.charCodeAt(0) === 0xFEFF) {\n input = input.slice(1);\n }\n }\n\n var state = new State$1(input, options);\n\n var nullpos = input.indexOf('\\0');\n\n if (nullpos !== -1) {\n state.position = nullpos;\n throwError(state, 'null byte is not allowed in input');\n }\n\n // Use 0 as string terminator. That significantly simplifies bounds check.\n state.input += '\\0';\n\n while (state.input.charCodeAt(state.position) === 0x20/* Space */) {\n state.lineIndent += 1;\n state.position += 1;\n }\n\n while (state.position < (state.length - 1)) {\n readDocument(state);\n }\n\n return state.documents;\n}\n\n\nfunction loadAll$1(input, iterator, options) {\n if (iterator !== null && typeof iterator === 'object' && typeof options === 'undefined') {\n options = iterator;\n iterator = null;\n }\n\n var documents = loadDocuments(input, options);\n\n if (typeof iterator !== 'function') {\n return documents;\n }\n\n for (var index = 0, length = documents.length; index < length; index += 1) {\n iterator(documents[index]);\n }\n}\n\n\nfunction load$1(input, options) {\n var documents = loadDocuments(input, options);\n\n if (documents.length === 0) {\n /*eslint-disable no-undefined*/\n return undefined;\n } else if (documents.length === 1) {\n return documents[0];\n }\n throw new exception('expected a single document in the stream, but found more');\n}\n\n\nvar loadAll_1 = loadAll$1;\nvar load_1 = load$1;\n\nvar loader = {\n\tloadAll: loadAll_1,\n\tload: load_1\n};\n\n/*eslint-disable no-use-before-define*/\n\n\n\n\n\nvar _toString = Object.prototype.toString;\nvar _hasOwnProperty = Object.prototype.hasOwnProperty;\n\nvar CHAR_BOM = 0xFEFF;\nvar CHAR_TAB = 0x09; /* Tab */\nvar CHAR_LINE_FEED = 0x0A; /* LF */\nvar CHAR_CARRIAGE_RETURN = 0x0D; /* CR */\nvar CHAR_SPACE = 0x20; /* Space */\nvar CHAR_EXCLAMATION = 0x21; /* ! */\nvar CHAR_DOUBLE_QUOTE = 0x22; /* \" */\nvar CHAR_SHARP = 0x23; /* # */\nvar CHAR_PERCENT = 0x25; /* % */\nvar CHAR_AMPERSAND = 0x26; /* & */\nvar CHAR_SINGLE_QUOTE = 0x27; /* ' */\nvar CHAR_ASTERISK = 0x2A; /* * */\nvar CHAR_COMMA = 0x2C; /* , */\nvar CHAR_MINUS = 0x2D; /* - */\nvar CHAR_COLON = 0x3A; /* : */\nvar CHAR_EQUALS = 0x3D; /* = */\nvar CHAR_GREATER_THAN = 0x3E; /* > */\nvar CHAR_QUESTION = 0x3F; /* ? */\nvar CHAR_COMMERCIAL_AT = 0x40; /* @ */\nvar CHAR_LEFT_SQUARE_BRACKET = 0x5B; /* [ */\nvar CHAR_RIGHT_SQUARE_BRACKET = 0x5D; /* ] */\nvar CHAR_GRAVE_ACCENT = 0x60; /* ` */\nvar CHAR_LEFT_CURLY_BRACKET = 0x7B; /* { */\nvar CHAR_VERTICAL_LINE = 0x7C; /* | */\nvar CHAR_RIGHT_CURLY_BRACKET = 0x7D; /* } */\n\nvar ESCAPE_SEQUENCES = {};\n\nESCAPE_SEQUENCES[0x00] = '\\\\0';\nESCAPE_SEQUENCES[0x07] = '\\\\a';\nESCAPE_SEQUENCES[0x08] = '\\\\b';\nESCAPE_SEQUENCES[0x09] = '\\\\t';\nESCAPE_SEQUENCES[0x0A] = '\\\\n';\nESCAPE_SEQUENCES[0x0B] = '\\\\v';\nESCAPE_SEQUENCES[0x0C] = '\\\\f';\nESCAPE_SEQUENCES[0x0D] = '\\\\r';\nESCAPE_SEQUENCES[0x1B] = '\\\\e';\nESCAPE_SEQUENCES[0x22] = '\\\\\"';\nESCAPE_SEQUENCES[0x5C] = '\\\\\\\\';\nESCAPE_SEQUENCES[0x85] = '\\\\N';\nESCAPE_SEQUENCES[0xA0] = '\\\\_';\nESCAPE_SEQUENCES[0x2028] = '\\\\L';\nESCAPE_SEQUENCES[0x2029] = '\\\\P';\n\nvar DEPRECATED_BOOLEANS_SYNTAX = [\n 'y', 'Y', 'yes', 'Yes', 'YES', 'on', 'On', 'ON',\n 'n', 'N', 'no', 'No', 'NO', 'off', 'Off', 'OFF'\n];\n\nvar DEPRECATED_BASE60_SYNTAX = /^[-+]?[0-9_]+(?::[0-9_]+)+(?:\\.[0-9_]*)?$/;\n\nfunction compileStyleMap(schema, map) {\n var result, keys, index, length, tag, style, type;\n\n if (map === null) return {};\n\n result = {};\n keys = Object.keys(map);\n\n for (index = 0, length = keys.length; index < length; index += 1) {\n tag = keys[index];\n style = String(map[tag]);\n\n if (tag.slice(0, 2) === '!!') {\n tag = 'tag:yaml.org,2002:' + tag.slice(2);\n }\n type = schema.compiledTypeMap['fallback'][tag];\n\n if (type && _hasOwnProperty.call(type.styleAliases, style)) {\n style = type.styleAliases[style];\n }\n\n result[tag] = style;\n }\n\n return result;\n}\n\nfunction encodeHex(character) {\n var string, handle, length;\n\n string = character.toString(16).toUpperCase();\n\n if (character <= 0xFF) {\n handle = 'x';\n length = 2;\n } else if (character <= 0xFFFF) {\n handle = 'u';\n length = 4;\n } else if (character <= 0xFFFFFFFF) {\n handle = 'U';\n length = 8;\n } else {\n throw new exception('code point within a string may not be greater than 0xFFFFFFFF');\n }\n\n return '\\\\' + handle + common.repeat('0', length - string.length) + string;\n}\n\n\nvar QUOTING_TYPE_SINGLE = 1,\n QUOTING_TYPE_DOUBLE = 2;\n\nfunction State(options) {\n this.schema = options['schema'] || _default;\n this.indent = Math.max(1, (options['indent'] || 2));\n this.noArrayIndent = options['noArrayIndent'] || false;\n this.skipInvalid = options['skipInvalid'] || false;\n this.flowLevel = (common.isNothing(options['flowLevel']) ? -1 : options['flowLevel']);\n this.styleMap = compileStyleMap(this.schema, options['styles'] || null);\n this.sortKeys = options['sortKeys'] || false;\n this.lineWidth = options['lineWidth'] || 80;\n this.noRefs = options['noRefs'] || false;\n this.noCompatMode = options['noCompatMode'] || false;\n this.condenseFlow = options['condenseFlow'] || false;\n this.quotingType = options['quotingType'] === '\"' ? QUOTING_TYPE_DOUBLE : QUOTING_TYPE_SINGLE;\n this.forceQuotes = options['forceQuotes'] || false;\n this.replacer = typeof options['replacer'] === 'function' ? options['replacer'] : null;\n\n this.implicitTypes = this.schema.compiledImplicit;\n this.explicitTypes = this.schema.compiledExplicit;\n\n this.tag = null;\n this.result = '';\n\n this.duplicates = [];\n this.usedDuplicates = null;\n}\n\n// Indents every line in a string. Empty lines (\\n only) are not indented.\nfunction indentString(string, spaces) {\n var ind = common.repeat(' ', spaces),\n position = 0,\n next = -1,\n result = '',\n line,\n length = string.length;\n\n while (position < length) {\n next = string.indexOf('\\n', position);\n if (next === -1) {\n line = string.slice(position);\n position = length;\n } else {\n line = string.slice(position, next + 1);\n position = next + 1;\n }\n\n if (line.length && line !== '\\n') result += ind;\n\n result += line;\n }\n\n return result;\n}\n\nfunction generateNextLine(state, level) {\n return '\\n' + common.repeat(' ', state.indent * level);\n}\n\nfunction testImplicitResolving(state, str) {\n var index, length, type;\n\n for (index = 0, length = state.implicitTypes.length; index < length; index += 1) {\n type = state.implicitTypes[index];\n\n if (type.resolve(str)) {\n return true;\n }\n }\n\n return false;\n}\n\n// [33] s-white ::= s-space | s-tab\nfunction isWhitespace(c) {\n return c === CHAR_SPACE || c === CHAR_TAB;\n}\n\n// Returns true if the character can be printed without escaping.\n// From YAML 1.2: \"any allowed characters known to be non-printable\n// should also be escaped. [However,] This isn’t mandatory\"\n// Derived from nb-char - \\t - #x85 - #xA0 - #x2028 - #x2029.\nfunction isPrintable(c) {\n return (0x00020 <= c && c <= 0x00007E)\n || ((0x000A1 <= c && c <= 0x00D7FF) && c !== 0x2028 && c !== 0x2029)\n || ((0x0E000 <= c && c <= 0x00FFFD) && c !== CHAR_BOM)\n || (0x10000 <= c && c <= 0x10FFFF);\n}\n\n// [34] ns-char ::= nb-char - s-white\n// [27] nb-char ::= c-printable - b-char - c-byte-order-mark\n// [26] b-char ::= b-line-feed | b-carriage-return\n// Including s-white (for some reason, examples doesn't match specs in this aspect)\n// ns-char ::= c-printable - b-line-feed - b-carriage-return - c-byte-order-mark\nfunction isNsCharOrWhitespace(c) {\n return isPrintable(c)\n && c !== CHAR_BOM\n // - b-char\n && c !== CHAR_CARRIAGE_RETURN\n && c !== CHAR_LINE_FEED;\n}\n\n// [127] ns-plain-safe(c) ::= c = flow-out ⇒ ns-plain-safe-out\n// c = flow-in ⇒ ns-plain-safe-in\n// c = block-key ⇒ ns-plain-safe-out\n// c = flow-key ⇒ ns-plain-safe-in\n// [128] ns-plain-safe-out ::= ns-char\n// [129] ns-plain-safe-in ::= ns-char - c-flow-indicator\n// [130] ns-plain-char(c) ::= ( ns-plain-safe(c) - “:” - “#” )\n// | ( /* An ns-char preceding */ “#” )\n// | ( “:” /* Followed by an ns-plain-safe(c) */ )\nfunction isPlainSafe(c, prev, inblock) {\n var cIsNsCharOrWhitespace = isNsCharOrWhitespace(c);\n var cIsNsChar = cIsNsCharOrWhitespace && !isWhitespace(c);\n return (\n // ns-plain-safe\n inblock ? // c = flow-in\n cIsNsCharOrWhitespace\n : cIsNsCharOrWhitespace\n // - c-flow-indicator\n && c !== CHAR_COMMA\n && c !== CHAR_LEFT_SQUARE_BRACKET\n && c !== CHAR_RIGHT_SQUARE_BRACKET\n && c !== CHAR_LEFT_CURLY_BRACKET\n && c !== CHAR_RIGHT_CURLY_BRACKET\n )\n // ns-plain-char\n && c !== CHAR_SHARP // false on '#'\n && !(prev === CHAR_COLON && !cIsNsChar) // false on ': '\n || (isNsCharOrWhitespace(prev) && !isWhitespace(prev) && c === CHAR_SHARP) // change to true on '[^ ]#'\n || (prev === CHAR_COLON && cIsNsChar); // change to true on ':[^ ]'\n}\n\n// Simplified test for values allowed as the first character in plain style.\nfunction isPlainSafeFirst(c) {\n // Uses a subset of ns-char - c-indicator\n // where ns-char = nb-char - s-white.\n // No support of ( ( “?” | “:” | “-” ) /* Followed by an ns-plain-safe(c)) */ ) part\n return isPrintable(c) && c !== CHAR_BOM\n && !isWhitespace(c) // - s-white\n // - (c-indicator ::=\n // “-” | “?” | “:” | “,” | “[” | “]” | “{” | “}”\n && c !== CHAR_MINUS\n && c !== CHAR_QUESTION\n && c !== CHAR_COLON\n && c !== CHAR_COMMA\n && c !== CHAR_LEFT_SQUARE_BRACKET\n && c !== CHAR_RIGHT_SQUARE_BRACKET\n && c !== CHAR_LEFT_CURLY_BRACKET\n && c !== CHAR_RIGHT_CURLY_BRACKET\n // | “#” | “&” | “*” | “!” | “|” | “=” | “>” | “'” | “\"”\n && c !== CHAR_SHARP\n && c !== CHAR_AMPERSAND\n && c !== CHAR_ASTERISK\n && c !== CHAR_EXCLAMATION\n && c !== CHAR_VERTICAL_LINE\n && c !== CHAR_EQUALS\n && c !== CHAR_GREATER_THAN\n && c !== CHAR_SINGLE_QUOTE\n && c !== CHAR_DOUBLE_QUOTE\n // | “%” | “@” | “`”)\n && c !== CHAR_PERCENT\n && c !== CHAR_COMMERCIAL_AT\n && c !== CHAR_GRAVE_ACCENT;\n}\n\n// Simplified test for values allowed as the last character in plain style.\nfunction isPlainSafeLast(c) {\n // just not whitespace or colon, it will be checked to be plain character later\n return !isWhitespace(c) && c !== CHAR_COLON;\n}\n\n// Same as 'string'.codePointAt(pos), but works in older browsers.\nfunction codePointAt(string, pos) {\n var first = string.charCodeAt(pos), second;\n if (first >= 0xD800 && first <= 0xDBFF && pos + 1 < string.length) {\n second = string.charCodeAt(pos + 1);\n if (second >= 0xDC00 && second <= 0xDFFF) {\n // https://mathiasbynens.be/notes/javascript-encoding#surrogate-formulae\n return (first - 0xD800) * 0x400 + second - 0xDC00 + 0x10000;\n }\n }\n return first;\n}\n\n// Determines whether block indentation indicator is required.\nfunction needIndentIndicator(string) {\n var leadingSpaceRe = /^\\n* /;\n return leadingSpaceRe.test(string);\n}\n\nvar STYLE_PLAIN = 1,\n STYLE_SINGLE = 2,\n STYLE_LITERAL = 3,\n STYLE_FOLDED = 4,\n STYLE_DOUBLE = 5;\n\n// Determines which scalar styles are possible and returns the preferred style.\n// lineWidth = -1 => no limit.\n// Pre-conditions: str.length > 0.\n// Post-conditions:\n// STYLE_PLAIN or STYLE_SINGLE => no \\n are in the string.\n// STYLE_LITERAL => no lines are suitable for folding (or lineWidth is -1).\n// STYLE_FOLDED => a line > lineWidth and can be folded (and lineWidth != -1).\nfunction chooseScalarStyle(string, singleLineOnly, indentPerLevel, lineWidth,\n testAmbiguousType, quotingType, forceQuotes, inblock) {\n\n var i;\n var char = 0;\n var prevChar = null;\n var hasLineBreak = false;\n var hasFoldableLine = false; // only checked if shouldTrackWidth\n var shouldTrackWidth = lineWidth !== -1;\n var previousLineBreak = -1; // count the first line correctly\n var plain = isPlainSafeFirst(codePointAt(string, 0))\n && isPlainSafeLast(codePointAt(string, string.length - 1));\n\n if (singleLineOnly || forceQuotes) {\n // Case: no block styles.\n // Check for disallowed characters to rule out plain and single.\n for (i = 0; i < string.length; char >= 0x10000 ? i += 2 : i++) {\n char = codePointAt(string, i);\n if (!isPrintable(char)) {\n return STYLE_DOUBLE;\n }\n plain = plain && isPlainSafe(char, prevChar, inblock);\n prevChar = char;\n }\n } else {\n // Case: block styles permitted.\n for (i = 0; i < string.length; char >= 0x10000 ? i += 2 : i++) {\n char = codePointAt(string, i);\n if (char === CHAR_LINE_FEED) {\n hasLineBreak = true;\n // Check if any line can be folded.\n if (shouldTrackWidth) {\n hasFoldableLine = hasFoldableLine ||\n // Foldable line = too long, and not more-indented.\n (i - previousLineBreak - 1 > lineWidth &&\n string[previousLineBreak + 1] !== ' ');\n previousLineBreak = i;\n }\n } else if (!isPrintable(char)) {\n return STYLE_DOUBLE;\n }\n plain = plain && isPlainSafe(char, prevChar, inblock);\n prevChar = char;\n }\n // in case the end is missing a \\n\n hasFoldableLine = hasFoldableLine || (shouldTrackWidth &&\n (i - previousLineBreak - 1 > lineWidth &&\n string[previousLineBreak + 1] !== ' '));\n }\n // Although every style can represent \\n without escaping, prefer block styles\n // for multiline, since they're more readable and they don't add empty lines.\n // Also prefer folding a super-long line.\n if (!hasLineBreak && !hasFoldableLine) {\n // Strings interpretable as another type have to be quoted;\n // e.g. the string 'true' vs. the boolean true.\n if (plain && !forceQuotes && !testAmbiguousType(string)) {\n return STYLE_PLAIN;\n }\n return quotingType === QUOTING_TYPE_DOUBLE ? STYLE_DOUBLE : STYLE_SINGLE;\n }\n // Edge case: block indentation indicator can only have one digit.\n if (indentPerLevel > 9 && needIndentIndicator(string)) {\n return STYLE_DOUBLE;\n }\n // At this point we know block styles are valid.\n // Prefer literal style unless we want to fold.\n if (!forceQuotes) {\n return hasFoldableLine ? STYLE_FOLDED : STYLE_LITERAL;\n }\n return quotingType === QUOTING_TYPE_DOUBLE ? STYLE_DOUBLE : STYLE_SINGLE;\n}\n\n// Note: line breaking/folding is implemented for only the folded style.\n// NB. We drop the last trailing newline (if any) of a returned block scalar\n// since the dumper adds its own newline. This always works:\n// • No ending newline => unaffected; already using strip \"-\" chomping.\n// • Ending newline => removed then restored.\n// Importantly, this keeps the \"+\" chomp indicator from gaining an extra line.\nfunction writeScalar(state, string, level, iskey, inblock) {\n state.dump = (function () {\n if (string.length === 0) {\n return state.quotingType === QUOTING_TYPE_DOUBLE ? '\"\"' : \"''\";\n }\n if (!state.noCompatMode) {\n if (DEPRECATED_BOOLEANS_SYNTAX.indexOf(string) !== -1 || DEPRECATED_BASE60_SYNTAX.test(string)) {\n return state.quotingType === QUOTING_TYPE_DOUBLE ? ('\"' + string + '\"') : (\"'\" + string + \"'\");\n }\n }\n\n var indent = state.indent * Math.max(1, level); // no 0-indent scalars\n // As indentation gets deeper, let the width decrease monotonically\n // to the lower bound min(state.lineWidth, 40).\n // Note that this implies\n // state.lineWidth ≤ 40 + state.indent: width is fixed at the lower bound.\n // state.lineWidth > 40 + state.indent: width decreases until the lower bound.\n // This behaves better than a constant minimum width which disallows narrower options,\n // or an indent threshold which causes the width to suddenly increase.\n var lineWidth = state.lineWidth === -1\n ? -1 : Math.max(Math.min(state.lineWidth, 40), state.lineWidth - indent);\n\n // Without knowing if keys are implicit/explicit, assume implicit for safety.\n var singleLineOnly = iskey\n // No block styles in flow mode.\n || (state.flowLevel > -1 && level >= state.flowLevel);\n function testAmbiguity(string) {\n return testImplicitResolving(state, string);\n }\n\n switch (chooseScalarStyle(string, singleLineOnly, state.indent, lineWidth,\n testAmbiguity, state.quotingType, state.forceQuotes && !iskey, inblock)) {\n\n case STYLE_PLAIN:\n return string;\n case STYLE_SINGLE:\n return \"'\" + string.replace(/'/g, \"''\") + \"'\";\n case STYLE_LITERAL:\n return '|' + blockHeader(string, state.indent)\n + dropEndingNewline(indentString(string, indent));\n case STYLE_FOLDED:\n return '>' + blockHeader(string, state.indent)\n + dropEndingNewline(indentString(foldString(string, lineWidth), indent));\n case STYLE_DOUBLE:\n return '\"' + escapeString(string) + '\"';\n default:\n throw new exception('impossible error: invalid scalar style');\n }\n }());\n}\n\n// Pre-conditions: string is valid for a block scalar, 1 <= indentPerLevel <= 9.\nfunction blockHeader(string, indentPerLevel) {\n var indentIndicator = needIndentIndicator(string) ? String(indentPerLevel) : '';\n\n // note the special case: the string '\\n' counts as a \"trailing\" empty line.\n var clip = string[string.length - 1] === '\\n';\n var keep = clip && (string[string.length - 2] === '\\n' || string === '\\n');\n var chomp = keep ? '+' : (clip ? '' : '-');\n\n return indentIndicator + chomp + '\\n';\n}\n\n// (See the note for writeScalar.)\nfunction dropEndingNewline(string) {\n return string[string.length - 1] === '\\n' ? string.slice(0, -1) : string;\n}\n\n// Note: a long line without a suitable break point will exceed the width limit.\n// Pre-conditions: every char in str isPrintable, str.length > 0, width > 0.\nfunction foldString(string, width) {\n // In folded style, $k$ consecutive newlines output as $k+1$ newlines—\n // unless they're before or after a more-indented line, or at the very\n // beginning or end, in which case $k$ maps to $k$.\n // Therefore, parse each chunk as newline(s) followed by a content line.\n var lineRe = /(\\n+)([^\\n]*)/g;\n\n // first line (possibly an empty line)\n var result = (function () {\n var nextLF = string.indexOf('\\n');\n nextLF = nextLF !== -1 ? nextLF : string.length;\n lineRe.lastIndex = nextLF;\n return foldLine(string.slice(0, nextLF), width);\n }());\n // If we haven't reached the first content line yet, don't add an extra \\n.\n var prevMoreIndented = string[0] === '\\n' || string[0] === ' ';\n var moreIndented;\n\n // rest of the lines\n var match;\n while ((match = lineRe.exec(string))) {\n var prefix = match[1], line = match[2];\n moreIndented = (line[0] === ' ');\n result += prefix\n + (!prevMoreIndented && !moreIndented && line !== ''\n ? '\\n' : '')\n + foldLine(line, width);\n prevMoreIndented = moreIndented;\n }\n\n return result;\n}\n\n// Greedy line breaking.\n// Picks the longest line under the limit each time,\n// otherwise settles for the shortest line over the limit.\n// NB. More-indented lines *cannot* be folded, as that would add an extra \\n.\nfunction foldLine(line, width) {\n if (line === '' || line[0] === ' ') return line;\n\n // Since a more-indented line adds a \\n, breaks can't be followed by a space.\n var breakRe = / [^ ]/g; // note: the match index will always be <= length-2.\n var match;\n // start is an inclusive index. end, curr, and next are exclusive.\n var start = 0, end, curr = 0, next = 0;\n var result = '';\n\n // Invariants: 0 <= start <= length-1.\n // 0 <= curr <= next <= max(0, length-2). curr - start <= width.\n // Inside the loop:\n // A match implies length >= 2, so curr and next are <= length-2.\n while ((match = breakRe.exec(line))) {\n next = match.index;\n // maintain invariant: curr - start <= width\n if (next - start > width) {\n end = (curr > start) ? curr : next; // derive end <= length-2\n result += '\\n' + line.slice(start, end);\n // skip the space that was output as \\n\n start = end + 1; // derive start <= length-1\n }\n curr = next;\n }\n\n // By the invariants, start <= length-1, so there is something left over.\n // It is either the whole string or a part starting from non-whitespace.\n result += '\\n';\n // Insert a break if the remainder is too long and there is a break available.\n if (line.length - start > width && curr > start) {\n result += line.slice(start, curr) + '\\n' + line.slice(curr + 1);\n } else {\n result += line.slice(start);\n }\n\n return result.slice(1); // drop extra \\n joiner\n}\n\n// Escapes a double-quoted string.\nfunction escapeString(string) {\n var result = '';\n var char = 0;\n var escapeSeq;\n\n for (var i = 0; i < string.length; char >= 0x10000 ? i += 2 : i++) {\n char = codePointAt(string, i);\n escapeSeq = ESCAPE_SEQUENCES[char];\n\n if (!escapeSeq && isPrintable(char)) {\n result += string[i];\n if (char >= 0x10000) result += string[i + 1];\n } else {\n result += escapeSeq || encodeHex(char);\n }\n }\n\n return result;\n}\n\nfunction writeFlowSequence(state, level, object) {\n var _result = '',\n _tag = state.tag,\n index,\n length,\n value;\n\n for (index = 0, length = object.length; index < length; index += 1) {\n value = object[index];\n\n if (state.replacer) {\n value = state.replacer.call(object, String(index), value);\n }\n\n // Write only valid elements, put null instead of invalid elements.\n if (writeNode(state, level, value, false, false) ||\n (typeof value === 'undefined' &&\n writeNode(state, level, null, false, false))) {\n\n if (_result !== '') _result += ',' + (!state.condenseFlow ? ' ' : '');\n _result += state.dump;\n }\n }\n\n state.tag = _tag;\n state.dump = '[' + _result + ']';\n}\n\nfunction writeBlockSequence(state, level, object, compact) {\n var _result = '',\n _tag = state.tag,\n index,\n length,\n value;\n\n for (index = 0, length = object.length; index < length; index += 1) {\n value = object[index];\n\n if (state.replacer) {\n value = state.replacer.call(object, String(index), value);\n }\n\n // Write only valid elements, put null instead of invalid elements.\n if (writeNode(state, level + 1, value, true, true, false, true) ||\n (typeof value === 'undefined' &&\n writeNode(state, level + 1, null, true, true, false, true))) {\n\n if (!compact || _result !== '') {\n _result += generateNextLine(state, level);\n }\n\n if (state.dump && CHAR_LINE_FEED === state.dump.charCodeAt(0)) {\n _result += '-';\n } else {\n _result += '- ';\n }\n\n _result += state.dump;\n }\n }\n\n state.tag = _tag;\n state.dump = _result || '[]'; // Empty sequence if no valid values.\n}\n\nfunction writeFlowMapping(state, level, object) {\n var _result = '',\n _tag = state.tag,\n objectKeyList = Object.keys(object),\n index,\n length,\n objectKey,\n objectValue,\n pairBuffer;\n\n for (index = 0, length = objectKeyList.length; index < length; index += 1) {\n\n pairBuffer = '';\n if (_result !== '') pairBuffer += ', ';\n\n if (state.condenseFlow) pairBuffer += '\"';\n\n objectKey = objectKeyList[index];\n objectValue = object[objectKey];\n\n if (state.replacer) {\n objectValue = state.replacer.call(object, objectKey, objectValue);\n }\n\n if (!writeNode(state, level, objectKey, false, false)) {\n continue; // Skip this pair because of invalid key;\n }\n\n if (state.dump.length > 1024) pairBuffer += '? ';\n\n pairBuffer += state.dump + (state.condenseFlow ? '\"' : '') + ':' + (state.condenseFlow ? '' : ' ');\n\n if (!writeNode(state, level, objectValue, false, false)) {\n continue; // Skip this pair because of invalid value.\n }\n\n pairBuffer += state.dump;\n\n // Both key and value are valid.\n _result += pairBuffer;\n }\n\n state.tag = _tag;\n state.dump = '{' + _result + '}';\n}\n\nfunction writeBlockMapping(state, level, object, compact) {\n var _result = '',\n _tag = state.tag,\n objectKeyList = Object.keys(object),\n index,\n length,\n objectKey,\n objectValue,\n explicitPair,\n pairBuffer;\n\n // Allow sorting keys so that the output file is deterministic\n if (state.sortKeys === true) {\n // Default sorting\n objectKeyList.sort();\n } else if (typeof state.sortKeys === 'function') {\n // Custom sort function\n objectKeyList.sort(state.sortKeys);\n } else if (state.sortKeys) {\n // Something is wrong\n throw new exception('sortKeys must be a boolean or a function');\n }\n\n for (index = 0, length = objectKeyList.length; index < length; index += 1) {\n pairBuffer = '';\n\n if (!compact || _result !== '') {\n pairBuffer += generateNextLine(state, level);\n }\n\n objectKey = objectKeyList[index];\n objectValue = object[objectKey];\n\n if (state.replacer) {\n objectValue = state.replacer.call(object, objectKey, objectValue);\n }\n\n if (!writeNode(state, level + 1, objectKey, true, true, true)) {\n continue; // Skip this pair because of invalid key.\n }\n\n explicitPair = (state.tag !== null && state.tag !== '?') ||\n (state.dump && state.dump.length > 1024);\n\n if (explicitPair) {\n if (state.dump && CHAR_LINE_FEED === state.dump.charCodeAt(0)) {\n pairBuffer += '?';\n } else {\n pairBuffer += '? ';\n }\n }\n\n pairBuffer += state.dump;\n\n if (explicitPair) {\n pairBuffer += generateNextLine(state, level);\n }\n\n if (!writeNode(state, level + 1, objectValue, true, explicitPair)) {\n continue; // Skip this pair because of invalid value.\n }\n\n if (state.dump && CHAR_LINE_FEED === state.dump.charCodeAt(0)) {\n pairBuffer += ':';\n } else {\n pairBuffer += ': ';\n }\n\n pairBuffer += state.dump;\n\n // Both key and value are valid.\n _result += pairBuffer;\n }\n\n state.tag = _tag;\n state.dump = _result || '{}'; // Empty mapping if no valid pairs.\n}\n\nfunction detectType(state, object, explicit) {\n var _result, typeList, index, length, type, style;\n\n typeList = explicit ? state.explicitTypes : state.implicitTypes;\n\n for (index = 0, length = typeList.length; index < length; index += 1) {\n type = typeList[index];\n\n if ((type.instanceOf || type.predicate) &&\n (!type.instanceOf || ((typeof object === 'object') && (object instanceof type.instanceOf))) &&\n (!type.predicate || type.predicate(object))) {\n\n if (explicit) {\n if (type.multi && type.representName) {\n state.tag = type.representName(object);\n } else {\n state.tag = type.tag;\n }\n } else {\n state.tag = '?';\n }\n\n if (type.represent) {\n style = state.styleMap[type.tag] || type.defaultStyle;\n\n if (_toString.call(type.represent) === '[object Function]') {\n _result = type.represent(object, style);\n } else if (_hasOwnProperty.call(type.represent, style)) {\n _result = type.represent[style](object, style);\n } else {\n throw new exception('!<' + type.tag + '> tag resolver accepts not \"' + style + '\" style');\n }\n\n state.dump = _result;\n }\n\n return true;\n }\n }\n\n return false;\n}\n\n// Serializes `object` and writes it to global `result`.\n// Returns true on success, or false on invalid object.\n//\nfunction writeNode(state, level, object, block, compact, iskey, isblockseq) {\n state.tag = null;\n state.dump = object;\n\n if (!detectType(state, object, false)) {\n detectType(state, object, true);\n }\n\n var type = _toString.call(state.dump);\n var inblock = block;\n var tagStr;\n\n if (block) {\n block = (state.flowLevel < 0 || state.flowLevel > level);\n }\n\n var objectOrArray = type === '[object Object]' || type === '[object Array]',\n duplicateIndex,\n duplicate;\n\n if (objectOrArray) {\n duplicateIndex = state.duplicates.indexOf(object);\n duplicate = duplicateIndex !== -1;\n }\n\n if ((state.tag !== null && state.tag !== '?') || duplicate || (state.indent !== 2 && level > 0)) {\n compact = false;\n }\n\n if (duplicate && state.usedDuplicates[duplicateIndex]) {\n state.dump = '*ref_' + duplicateIndex;\n } else {\n if (objectOrArray && duplicate && !state.usedDuplicates[duplicateIndex]) {\n state.usedDuplicates[duplicateIndex] = true;\n }\n if (type === '[object Object]') {\n if (block && (Object.keys(state.dump).length !== 0)) {\n writeBlockMapping(state, level, state.dump, compact);\n if (duplicate) {\n state.dump = '&ref_' + duplicateIndex + state.dump;\n }\n } else {\n writeFlowMapping(state, level, state.dump);\n if (duplicate) {\n state.dump = '&ref_' + duplicateIndex + ' ' + state.dump;\n }\n }\n } else if (type === '[object Array]') {\n if (block && (state.dump.length !== 0)) {\n if (state.noArrayIndent && !isblockseq && level > 0) {\n writeBlockSequence(state, level - 1, state.dump, compact);\n } else {\n writeBlockSequence(state, level, state.dump, compact);\n }\n if (duplicate) {\n state.dump = '&ref_' + duplicateIndex + state.dump;\n }\n } else {\n writeFlowSequence(state, level, state.dump);\n if (duplicate) {\n state.dump = '&ref_' + duplicateIndex + ' ' + state.dump;\n }\n }\n } else if (type === '[object String]') {\n if (state.tag !== '?') {\n writeScalar(state, state.dump, level, iskey, inblock);\n }\n } else if (type === '[object Undefined]') {\n return false;\n } else {\n if (state.skipInvalid) return false;\n throw new exception('unacceptable kind of an object to dump ' + type);\n }\n\n if (state.tag !== null && state.tag !== '?') {\n // Need to encode all characters except those allowed by the spec:\n //\n // [35] ns-dec-digit ::= [#x30-#x39] /* 0-9 */\n // [36] ns-hex-digit ::= ns-dec-digit\n // | [#x41-#x46] /* A-F */ | [#x61-#x66] /* a-f */\n // [37] ns-ascii-letter ::= [#x41-#x5A] /* A-Z */ | [#x61-#x7A] /* a-z */\n // [38] ns-word-char ::= ns-dec-digit | ns-ascii-letter | “-”\n // [39] ns-uri-char ::= “%” ns-hex-digit ns-hex-digit | ns-word-char | “#”\n // | “;” | “/” | “?” | “:” | “@” | “&” | “=” | “+” | “$” | “,”\n // | “_” | “.” | “!” | “~” | “*” | “'” | “(” | “)” | “[” | “]”\n //\n // Also need to encode '!' because it has special meaning (end of tag prefix).\n //\n tagStr = encodeURI(\n state.tag[0] === '!' ? state.tag.slice(1) : state.tag\n ).replace(/!/g, '%21');\n\n if (state.tag[0] === '!') {\n tagStr = '!' + tagStr;\n } else if (tagStr.slice(0, 18) === 'tag:yaml.org,2002:') {\n tagStr = '!!' + tagStr.slice(18);\n } else {\n tagStr = '!<' + tagStr + '>';\n }\n\n state.dump = tagStr + ' ' + state.dump;\n }\n }\n\n return true;\n}\n\nfunction getDuplicateReferences(object, state) {\n var objects = [],\n duplicatesIndexes = [],\n index,\n length;\n\n inspectNode(object, objects, duplicatesIndexes);\n\n for (index = 0, length = duplicatesIndexes.length; index < length; index += 1) {\n state.duplicates.push(objects[duplicatesIndexes[index]]);\n }\n state.usedDuplicates = new Array(length);\n}\n\nfunction inspectNode(object, objects, duplicatesIndexes) {\n var objectKeyList,\n index,\n length;\n\n if (object !== null && typeof object === 'object') {\n index = objects.indexOf(object);\n if (index !== -1) {\n if (duplicatesIndexes.indexOf(index) === -1) {\n duplicatesIndexes.push(index);\n }\n } else {\n objects.push(object);\n\n if (Array.isArray(object)) {\n for (index = 0, length = object.length; index < length; index += 1) {\n inspectNode(object[index], objects, duplicatesIndexes);\n }\n } else {\n objectKeyList = Object.keys(object);\n\n for (index = 0, length = objectKeyList.length; index < length; index += 1) {\n inspectNode(object[objectKeyList[index]], objects, duplicatesIndexes);\n }\n }\n }\n }\n}\n\nfunction dump$1(input, options) {\n options = options || {};\n\n var state = new State(options);\n\n if (!state.noRefs) getDuplicateReferences(input, state);\n\n var value = input;\n\n if (state.replacer) {\n value = state.replacer.call({ '': value }, '', value);\n }\n\n if (writeNode(state, 0, value, true, true)) return state.dump + '\\n';\n\n return '';\n}\n\nvar dump_1 = dump$1;\n\nvar dumper = {\n\tdump: dump_1\n};\n\nfunction renamed(from, to) {\n return function () {\n throw new Error('Function yaml.' + from + ' is removed in js-yaml 4. ' +\n 'Use yaml.' + to + ' instead, which is now safe by default.');\n };\n}\n\n\nvar Type = type;\nvar Schema = schema;\nvar FAILSAFE_SCHEMA = failsafe;\nvar JSON_SCHEMA = json;\nvar CORE_SCHEMA = core;\nvar DEFAULT_SCHEMA = _default;\nvar load = loader.load;\nvar loadAll = loader.loadAll;\nvar dump = dumper.dump;\nvar YAMLException = exception;\n\n// Re-export all types in case user wants to create custom schema\nvar types = {\n binary: binary,\n float: float,\n map: map,\n null: _null,\n pairs: pairs,\n set: set,\n timestamp: timestamp,\n bool: bool,\n int: int,\n merge: merge,\n omap: omap,\n seq: seq,\n str: str\n};\n\n// Removed functions from JS-YAML 3.0.x\nvar safeLoad = renamed('safeLoad', 'load');\nvar safeLoadAll = renamed('safeLoadAll', 'loadAll');\nvar safeDump = renamed('safeDump', 'dump');\n\nvar jsYaml = {\n\tType: Type,\n\tSchema: Schema,\n\tFAILSAFE_SCHEMA: FAILSAFE_SCHEMA,\n\tJSON_SCHEMA: JSON_SCHEMA,\n\tCORE_SCHEMA: CORE_SCHEMA,\n\tDEFAULT_SCHEMA: DEFAULT_SCHEMA,\n\tload: load,\n\tloadAll: loadAll,\n\tdump: dump,\n\tYAMLException: YAMLException,\n\ttypes: types,\n\tsafeLoad: safeLoad,\n\tsafeLoadAll: safeLoadAll,\n\tsafeDump: safeDump\n};\n\nexport { CORE_SCHEMA, DEFAULT_SCHEMA, FAILSAFE_SCHEMA, JSON_SCHEMA, Schema, Type, YAMLException, jsYaml as default, dump, load, loadAll, safeDump, safeLoad, safeLoadAll, types };\n","/**\n * Mokkun YAML Parser\n * YAMLテキストを型安全にパースする\n */\n\nimport yaml from 'js-yaml'\nimport type {\n MokkunSchema,\n MokkunSchemaRaw,\n ScreenDefinition,\n ScreenDefinitionRaw,\n InputField,\n InputFieldRaw,\n InputFieldType,\n CommonComponent,\n CommonComponentRaw,\n ValidationRule,\n ValidationRuleRaw,\n FormSection,\n SelectOption,\n} from '../types/schema'\n\n// =============================================================================\n// Error Types / エラー型\n// =============================================================================\n\n/**\n * パースエラーの種類\n */\nexport type ParseErrorType =\n | 'YAML_SYNTAX_ERROR'\n | 'SCHEMA_VALIDATION_ERROR'\n | 'MISSING_REQUIRED_FIELD'\n | 'INVALID_FIELD_TYPE'\n | 'INVALID_VALUE'\n\n/**\n * パースエラー\n */\nexport interface ParseError {\n type: ParseErrorType\n message: string\n path?: string\n line?: number\n column?: number\n}\n\n/**\n * パース結果\n */\nexport type ParseResult<T> =\n | { success: true; data: T }\n | { success: false; errors: ParseError[] }\n\n// =============================================================================\n// Validation Helpers / バリデーションヘルパー\n// =============================================================================\n\nexport const VALID_FIELD_TYPES: InputFieldType[] = [\n 'text',\n 'number',\n 'textarea',\n 'select',\n 'multi_select',\n 'combobox',\n 'radio_group',\n 'checkbox',\n 'checkbox_group',\n 'date_picker',\n 'time_picker',\n 'duration_picker',\n 'duration_input',\n 'file_upload',\n 'repeater',\n 'data_table',\n 'google_map_embed',\n 'photo_manager',\n 'toggle',\n 'image_uploader',\n 'badge',\n 'browser',\n 'calendar',\n 'heading',\n 'tooltip',\n 'pagination',\n 'float_area',\n 'loader',\n 'notification_bar',\n 'response_message',\n 'timeline',\n 'chip',\n 'status_label',\n 'segmented_control',\n 'tabs',\n 'line_clamp',\n 'disclosure',\n 'accordion_panel',\n 'section_nav',\n 'stepper',\n 'information_panel',\n 'dropdown',\n 'delete_confirm_dialog',\n 'definition_list',\n]\n\n// Field types that are used in YAML but not yet fully implemented\n// These will be treated as 'text' fallback during normalization\nexport const PLACEHOLDER_FIELD_TYPES: string[] = [\n // All placeholder types have been implemented\n]\n\nconst VALID_ACTION_TYPES = ['submit', 'navigate', 'custom', 'reset'] as const\n\nconst VALID_COMPONENT_TYPES = ['field_group', 'action_group', 'layout', 'template'] as const\n\n/**\n * 値が存在するかチェック\n */\nfunction isDefined<T>(value: T | undefined | null): value is T {\n return value !== undefined && value !== null\n}\n\n/**\n * オブジェクトかどうかチェック\n */\nfunction isObject(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value)\n}\n\n/**\n * 配列かどうかチェック\n */\nfunction isArray(value: unknown): value is unknown[] {\n return Array.isArray(value)\n}\n\n/**\n * 文字列かどうかチェック\n */\nfunction isString(value: unknown): value is string {\n return typeof value === 'string'\n}\n\n// =============================================================================\n// Normalizers / 正規化関数\n// =============================================================================\n\n/**\n * 文字列を安全なキーに変換(スペースをアンダースコアに、特殊文字を削除)\n */\nfunction toSafeKey(name: string): string {\n return name\n .toLowerCase()\n .replace(/[()()]/g, '')\n .replace(/[・]/g, '_')\n .replace(/\\s+/g, '_')\n .replace(/[^a-z0-9_\\u3040-\\u309f\\u30a0-\\u30ff\\u4e00-\\u9faf]/g, '')\n}\n\n/**\n * 配列形式の入力フィールドを正規化\n */\nfunction normalizeInputField(raw: InputFieldRaw): InputField {\n const id = raw.id ?? raw.field_name ?? 'unknown'\n const label = raw.label ?? raw.field_name ?? 'Unknown'\n\n // 配列形式のオプションをSelectOption形式に変換\n let options: SelectOption[] | string | undefined\n if (raw.options) {\n if (isArray(raw.options) && raw.options.length > 0) {\n if (isString(raw.options[0])) {\n // 文字列配列の場合、SelectOption配列に変換\n options = (raw.options as string[]).map(opt => ({\n value: opt,\n label: opt,\n }))\n } else {\n options = raw.options as SelectOption[]\n }\n } else if (isString(raw.options)) {\n options = raw.options\n }\n }\n\n // 基本的なフィールドを構築\n const base = {\n id,\n label,\n description: raw.description,\n required: raw.required,\n placeholder: raw.placeholder,\n ...(raw.visible_when ? { visible_when: raw.visible_when as import('../types/schema').Condition } : {}),\n }\n\n // フィールドタイプに応じて変換\n const fieldType = raw.type as InputFieldType\n\n switch (fieldType) {\n case 'text':\n return {\n ...base,\n type: 'text',\n input_type: raw.input_type as 'text' | 'email' | 'url' | 'tel' | 'password' | undefined,\n }\n case 'number':\n return {\n ...base,\n type: 'number',\n min: raw.min as number | undefined,\n max: raw.max as number | undefined,\n unit: raw.unit,\n }\n case 'textarea':\n return {\n ...base,\n type: 'textarea',\n rows: raw.rows as number | undefined,\n }\n case 'select':\n return {\n ...base,\n type: 'select',\n options: options ?? [],\n }\n case 'multi_select':\n return {\n ...base,\n type: 'multi_select',\n options: options ?? [],\n }\n case 'radio_group':\n return {\n ...base,\n type: 'radio_group',\n options: options ?? [],\n }\n case 'checkbox_group':\n return {\n ...base,\n type: 'checkbox_group',\n options: options ?? [],\n }\n case 'date_picker':\n return {\n ...base,\n type: 'date_picker',\n }\n case 'time_picker':\n return {\n ...base,\n type: 'time_picker',\n }\n case 'duration_picker':\n return {\n ...base,\n type: 'duration_picker',\n units: raw.units as ('hours' | 'minutes' | 'seconds' | 'days')[] | undefined,\n }\n case 'duration_input':\n return {\n ...base,\n type: 'duration_input',\n display_unit: raw.unit as 'hours' | 'minutes' | 'seconds' | undefined,\n }\n case 'file_upload':\n return {\n ...base,\n type: 'file_upload',\n accept: raw.accepted_types?.split(',').map(t => t.trim()) ?? raw.accept as string[] | undefined,\n multiple: raw.multiple as boolean | undefined,\n }\n case 'repeater':\n return {\n ...base,\n type: 'repeater',\n item_fields: (raw.item_fields as InputFieldRaw[] | undefined)?.map(normalizeInputField) ?? [],\n }\n case 'data_table': {\n // data行にidがない場合は自動生成\n const rawData = raw.data as import('../types/schema').DataTableRow[] | undefined\n const normalizedData = rawData?.map((row, index) => {\n if (row.id === undefined && row.id !== 0) {\n return { ...row, id: `row-${index}` }\n }\n return row\n })\n return {\n ...base,\n type: 'data_table',\n columns: (raw.columns ?? []) as import('../types/schema').DataTableColumn[],\n data: normalizedData,\n selection: raw.selection as 'none' | 'single' | 'multiple' | undefined,\n row_actions: raw.row_actions as import('../types/schema').DataTableRowAction[] | undefined,\n default_sort: raw.default_sort as import('../types/schema').DataTableSortConfig | undefined,\n pagination: raw.pagination as import('../types/schema').DataTablePaginationConfig | undefined,\n filters: raw.filters as import('../types/schema').DataTableFilterConfig | undefined,\n empty_state: raw.empty_state as import('../types/schema').DataTableEmptyState | undefined,\n height: raw.height as string | undefined,\n striped: raw.striped as boolean | undefined,\n hoverable: raw.hoverable as boolean | undefined,\n bordered: raw.bordered as boolean | undefined,\n compact: raw.compact as boolean | undefined,\n responsive: raw.responsive as boolean | undefined,\n }\n }\n case 'google_map_embed':\n return {\n ...base,\n type: 'google_map_embed',\n height: raw.height as string | undefined,\n width: raw.width as string | undefined,\n show_open_link: raw.show_open_link as boolean | undefined,\n zoom: raw.zoom as number | undefined,\n }\n case 'photo_manager':\n return {\n ...base,\n type: 'photo_manager',\n photos: raw.photos as import('../types/schema').PhotoConfig[] | undefined,\n max_photos: raw.max_photos as number | undefined,\n max_file_size: raw.max_file_size as number | undefined,\n accepted_formats: raw.accepted_formats as string[] | undefined,\n columns: raw.columns as number | undefined,\n }\n case 'image_uploader':\n return {\n ...base,\n type: 'image_uploader',\n accepted_formats: raw.accepted_formats as string[] | undefined,\n max_file_size: raw.max_file_size as number | undefined,\n max_files: raw.max_files as number | undefined,\n min_files: raw.min_files as number | undefined,\n }\n case 'browser':\n return {\n ...base,\n type: 'browser',\n items: raw.items as import('../types/schema').BrowserItemSchema[] | undefined ?? [],\n default: raw.default as string | undefined,\n maxColumns: raw.max_columns as number | undefined,\n height: raw.height as string | undefined,\n }\n case 'calendar':\n return {\n ...base,\n type: 'calendar',\n default: raw.default as string | undefined,\n from: raw.from as string | undefined,\n to: raw.to as string | undefined,\n weekStartsOn: raw.week_starts_on as 0 | 1 | undefined,\n locale: raw.locale as string | undefined,\n }\n case 'combobox':\n return {\n ...base,\n type: 'combobox',\n mode: raw.mode as 'single' | 'multi' | undefined,\n options: options,\n searchable: raw.searchable as boolean | undefined,\n async_loader: raw.async_loader as string | undefined,\n min_search_length: raw.min_search_length as number | undefined,\n debounce_ms: raw.debounce_ms as number | undefined,\n clearable: raw.clearable as boolean | undefined,\n max_selections: raw.max_selections as number | undefined,\n }\n case 'checkbox':\n return {\n ...base,\n type: 'checkbox',\n checked_label: raw.checked_label as string | undefined,\n unchecked_label: raw.unchecked_label as string | undefined,\n size: raw.size as 'small' | 'medium' | 'large' | undefined,\n name: raw.name as string | undefined,\n label_position: raw.label_position as 'left' | 'right' | undefined,\n }\n case 'toggle':\n return {\n ...base,\n type: 'toggle',\n checked_label: raw.checked_label as string | undefined,\n unchecked_label: raw.unchecked_label as string | undefined,\n size: raw.size as 'small' | 'medium' | 'large' | undefined,\n name: raw.name as string | undefined,\n label_position: raw.label_position as 'left' | 'right' | undefined,\n }\n case 'badge':\n return {\n ...base,\n type: 'badge',\n color: raw.color as 'gray' | 'blue' | 'green' | 'yellow' | 'red' | undefined,\n size: raw.size as 'small' | 'medium' | undefined,\n dot: raw.dot as boolean | undefined,\n count: raw.count as number | undefined,\n max_count: raw.max_count as number | undefined,\n text: raw.text as string | undefined,\n }\n case 'heading':\n return {\n ...base,\n type: 'heading',\n level: (raw.level ?? 2) as 1 | 2 | 3 | 4 | 5 | 6,\n text: (raw.label ?? raw.text ?? '') as string,\n size: raw.size as 'xs' | 'sm' | 'md' | 'lg' | 'xl' | '2xl' | undefined,\n align: raw.align as 'left' | 'center' | 'right' | undefined,\n color: raw.color as 'default' | 'primary' | 'secondary' | 'muted' | 'danger' | 'success' | 'warning' | undefined,\n icon: raw.icon as string | undefined,\n }\n case 'tooltip':\n return {\n ...base,\n type: 'tooltip',\n content: (raw.content ?? '') as string,\n position: raw.position as 'top' | 'bottom' | 'left' | 'right' | undefined,\n delay: raw.delay as number | undefined,\n show_arrow: raw.show_arrow as boolean | undefined,\n is_html: raw.is_html as boolean | undefined,\n max_width: raw.max_width as string | undefined,\n }\n case 'pagination':\n return {\n ...base,\n type: 'pagination',\n total_items: (raw.total_items ?? 0) as number,\n current_page: raw.current_page as number | undefined,\n page_size: raw.page_size as number | undefined,\n page_size_options: raw.page_size_options as number[] | undefined,\n show_page_size_selector: raw.show_page_size_selector as boolean | undefined,\n show_item_count: raw.show_item_count as boolean | undefined,\n show_jump_buttons: raw.show_jump_buttons as boolean | undefined,\n max_page_buttons: raw.max_page_buttons as number | undefined,\n compact: raw.compact as boolean | undefined,\n align: raw.align as 'left' | 'center' | 'right' | undefined,\n }\n case 'float_area':\n return {\n ...base,\n type: 'float_area',\n position: raw.position as 'top' | 'bottom' | undefined,\n show_shadow: raw.show_shadow as boolean | undefined,\n show_border: raw.show_border as boolean | undefined,\n z_index: raw.z_index as number | undefined,\n responsive: raw.responsive as boolean | undefined,\n sticky: raw.sticky as boolean | undefined,\n align: (raw.float_align ?? raw.align) as 'left' | 'center' | 'right' | 'space-between' | undefined,\n padding: raw.padding as string | undefined,\n gap: raw.gap as string | undefined,\n aria_label: raw.aria_label as string | undefined,\n }\n case 'loader':\n return {\n ...base,\n type: 'loader',\n size: (raw.loader_size ?? raw.size) as 'small' | 'medium' | 'large' | undefined,\n loaderType: (raw.loader_type ?? raw.loaderType) as 'primary' | 'light' | undefined,\n overlay: raw.overlay as boolean | undefined,\n showProgress: (raw.show_progress ?? raw.showProgress) as boolean | undefined,\n initialProgress: (raw.initial_progress ?? raw.initialProgress) as number | undefined,\n }\n default:\n // 未知のタイプ(placeholder types等)はそのまま渡す\n // レンダリング時にフォールバック表示される\n return {\n ...base,\n type: fieldType as InputFieldType,\n } as InputField\n }\n}\n\n/**\n * フォームセクションからフィールドを抽出して正規化\n */\nfunction normalizeFieldsFromSections(sections: FormSection[]): InputField[] {\n const fields: InputField[] = []\n\n for (const section of sections) {\n if (section.input_fields) {\n for (const rawField of section.input_fields) {\n fields.push(normalizeInputField(rawField))\n }\n }\n }\n\n return fields\n}\n\n/**\n * display_fieldsからDataTableFieldを生成\n */\nfunction createDataTableFromDisplayFields(\n displayFields: string[],\n filters?: string[],\n screenName?: string\n): InputField {\n // カラム定義を生成\n const columns: import('../types/schema').DataTableColumn[] = displayFields.map((fieldName, index) => ({\n id: `col_${index}`,\n label: fieldName,\n sortable: true,\n }))\n\n // フィルター設定を生成\n let filterConfig: import('../types/schema').DataTableFilterConfig | undefined\n if (filters && filters.length > 0) {\n filterConfig = {\n enabled: true,\n show_search: filters.some(f => f.includes('キーワード') || f.includes('検索')),\n fields: filters\n .filter(f => !f.includes('キーワード') && !f.includes('検索'))\n .map((filterName, index) => ({\n id: `filter_${index}`,\n label: filterName,\n column: `col_${index}`, // 対応するカラムIDを設定\n type: 'select' as const,\n options: [] as import('../types/schema').SelectOption[],\n })),\n }\n }\n\n const dataTableField: InputField = {\n id: screenName ? toSafeKey(screenName) + '_table' : 'data_table',\n type: 'data_table',\n label: screenName ?? '一覧',\n columns,\n data: [], // データは空(実際のデータは外部から注入)\n selection: 'single',\n pagination: {\n enabled: true,\n page_size: 10,\n page_size_options: [10, 25, 50, 100],\n },\n filters: filterConfig,\n empty_state: {\n title: 'データがありません',\n description: '表示するデータが存在しません',\n icon: '📭',\n },\n hoverable: true,\n striped: true,\n }\n\n return dataTableField\n}\n\n/**\n * セクションを正規化(フィールドを正規化しつつセクション構造を保持)\n */\nfunction normalizeSection(rawSection: FormSection): FormSection {\n return {\n section_name: rawSection.section_name,\n icon: rawSection.icon,\n publish_toggle: rawSection.publish_toggle,\n input_fields: rawSection.input_fields?.map(normalizeInputField) as InputFieldRaw[] | undefined,\n }\n}\n\n/**\n * YAML形式のAppHeader設定を正規化(snake_case → camelCase)\n */\nfunction normalizeAppHeader(\n raw: Record<string, unknown> | undefined\n): import('../types/schema').AppHeaderConfigSchema | undefined {\n if (!raw) return undefined\n\n return {\n logo: raw.logo as string | undefined,\n logoAlt: raw.logo_alt as string | undefined,\n logoHref: raw.logo_href as string | undefined,\n appName: (raw.app_name ?? raw.appName ?? '') as string,\n tenants: raw.tenants as import('../types/schema').TenantSchema[] | undefined,\n currentTenantId: (raw.current_tenant_id ?? raw.currentTenantId) as string | undefined,\n userInfo: raw.user_info\n ? {\n name: (raw.user_info as Record<string, unknown>).name as string,\n email: (raw.user_info as Record<string, unknown>).email as string | undefined,\n avatarUrl: ((raw.user_info as Record<string, unknown>).avatar_url ??\n (raw.user_info as Record<string, unknown>).avatarUrl) as string | undefined,\n }\n : { name: '' },\n navigations: (raw.navigations as Record<string, unknown>[] | undefined)?.map((nav) => ({\n id: nav.id as string,\n label: nav.label as string,\n href: nav.href as string | undefined,\n active: nav.active as boolean | undefined,\n disabled: nav.disabled as boolean | undefined,\n dropdown: (nav.dropdown as Record<string, unknown>[] | undefined)?.map((item) => ({\n id: item.id as string,\n label: item.label as string,\n href: item.href as string | undefined,\n divider: item.divider as boolean | undefined,\n })),\n })),\n appLauncher: (raw.app_launcher ?? raw.appLauncher) as import('../types/schema').AppLauncherItemSchema[] | undefined,\n helpPageUrl: (raw.help_page_url ?? raw.helpPageUrl) as string | undefined,\n showReleaseNote: (raw.show_release_note ?? raw.showReleaseNote) as boolean | undefined,\n releaseNoteText: (raw.release_note_text ?? raw.releaseNoteText) as string | undefined,\n showDataSync: (raw.show_data_sync ?? raw.showDataSync) as boolean | undefined,\n }\n}\n\n/**\n * YAML形式のAppNavi設定を正規化(snake_case → camelCase)\n */\nfunction normalizeAppNavi(\n raw: Record<string, unknown> | undefined\n): import('../types/schema').AppNaviConfigSchema | undefined {\n if (!raw) return undefined\n\n const items = (raw.items as Record<string, unknown>[] | undefined)?.map((item) => ({\n id: item.id as string,\n label: item.label as string,\n type: item.type as 'button' | 'anchor' | 'dropdown',\n icon: item.icon as string | undefined,\n disabled: item.disabled as boolean | undefined,\n current: item.current as boolean | undefined,\n href: item.href as string | undefined,\n target: item.target as '_blank' | '_self' | '_parent' | '_top' | undefined,\n dropdownItems: ((item.dropdown_items ?? item.dropdownItems) as Record<string, unknown>[] | undefined)?.map(\n (dropdownItem) => ({\n id: dropdownItem.id as string,\n label: dropdownItem.label as string,\n icon: dropdownItem.icon as string | undefined,\n disabled: dropdownItem.disabled as boolean | undefined,\n href: dropdownItem.href as string | undefined,\n })\n ),\n })) ?? []\n\n return {\n label: raw.label as string | undefined,\n items,\n }\n}\n\n/**\n * 配列形式の画面定義を正規化\n */\nfunction normalizeScreenDefinition(raw: ScreenDefinitionRaw): ScreenDefinition {\n // タイトルを決定(name, title, purposeの順で優先)\n const title = raw.title ?? raw.name ?? 'Untitled'\n\n // セクションと フィールドを正規化\n let sections: FormSection[] | undefined\n let fields: InputField[] | undefined\n\n if (raw.sections && raw.sections.length > 0) {\n // セクションを正規化して保持(SectionNavで使用)\n sections = raw.sections.map(normalizeSection)\n // セクションからフィールドも抽出(フォーム全体の処理用)\n fields = normalizeFieldsFromSections(raw.sections)\n } else if (raw.fields) {\n // 通常のfieldsを使用\n fields = (raw.fields as InputFieldRaw[]).map(normalizeInputField)\n } else if (raw.display_fields && isArray(raw.display_fields)) {\n // display_fieldsがある場合はdata_tableフィールドを自動生成\n const dataTableField = createDataTableFromDisplayFields(\n raw.display_fields as string[],\n raw.filters as string[] | undefined,\n raw.name\n )\n fields = [dataTableField]\n }\n\n // input_fieldsがある場合(配列形式でのフィールド定義)\n if (!fields && raw.input_fields && isArray(raw.input_fields)) {\n fields = (raw.input_fields as InputFieldRaw[]).map(normalizeInputField)\n }\n\n // アクションを正規化(文字列配列の場合も対応)\n let actions = raw.actions\n if (actions && isArray(actions)) {\n actions = actions.map((action, index) => {\n if (isString(action)) {\n // 文字列の場合はボタンラベルとして扱う\n return {\n id: `action_${index}`,\n type: 'submit' as const,\n label: action,\n style: index === 0 ? 'primary' as const : 'secondary' as const,\n }\n }\n return action\n })\n }\n\n return {\n title,\n description: raw.description ?? raw.purpose,\n app_header: normalizeAppHeader(raw.app_header as Record<string, unknown> | undefined),\n app_navi: normalizeAppNavi(raw.app_navi as Record<string, unknown> | undefined),\n sections,\n fields,\n actions,\n wizard: raw.wizard,\n layout: raw.layout,\n }\n}\n\n/**\n * 配列形式のviewを正規化\n */\nfunction normalizeView(\n view: Record<string, ScreenDefinitionRaw> | ScreenDefinitionRaw[]\n): Record<string, ScreenDefinition> {\n if (isArray(view)) {\n // 配列形式の場合、オブジェクト形式に変換\n const result: Record<string, ScreenDefinition> = {}\n\n for (const screen of view) {\n const key = screen.name ? toSafeKey(screen.name) : `screen_${Object.keys(result).length}`\n result[key] = normalizeScreenDefinition(screen)\n }\n\n return result\n }\n\n // オブジェクト形式の場合、各画面を正規化\n const result: Record<string, ScreenDefinition> = {}\n\n for (const [key, screen] of Object.entries(view)) {\n result[key] = normalizeScreenDefinition(screen as ScreenDefinitionRaw)\n }\n\n return result\n}\n\n/**\n * 配列形式のcommon_componentsを正規化\n */\nfunction normalizeCommonComponents(\n components: Record<string, CommonComponent> | CommonComponentRaw[] | undefined\n): Record<string, CommonComponent> | undefined {\n if (!components) return undefined\n\n if (isArray(components)) {\n const result: Record<string, CommonComponent> = {}\n\n for (const comp of components) {\n const key = toSafeKey(comp.component_name)\n result[key] = {\n name: comp.component_name,\n description: comp.description,\n type: 'field_group', // デフォルト\n }\n }\n\n return result\n }\n\n return components\n}\n\n/**\n * 配列形式のvalidationsを正規化\n */\nfunction normalizeValidations(\n validations: Record<string, ValidationRule> | ValidationRuleRaw[] | undefined\n): Record<string, ValidationRule> | undefined {\n if (!validations) return undefined\n\n if (isArray(validations)) {\n const result: Record<string, ValidationRule> = {}\n\n for (const rule of validations) {\n const key = toSafeKey(rule.field)\n result[key] = {\n name: rule.field,\n rules: {\n message: rule.rule,\n },\n message: rule.rule,\n }\n }\n\n return result\n }\n\n return validations\n}\n\n/**\n * 生のスキーマデータを正規化されたMokkunSchemaに変換\n */\nfunction normalizeSchema(raw: MokkunSchemaRaw): MokkunSchema {\n return {\n view: normalizeView(raw.view),\n common_components: normalizeCommonComponents(raw.common_components),\n validations: normalizeValidations(raw.validations),\n }\n}\n\n// =============================================================================\n// Validators / バリデーター\n// =============================================================================\n\n/**\n * 入力フィールドをバリデート\n */\nfunction validateInputField(\n field: unknown,\n path: string\n): ParseError[] {\n const errors: ParseError[] = []\n\n if (!isObject(field)) {\n errors.push({\n type: 'INVALID_VALUE',\n message: 'Field must be an object',\n path,\n })\n return errors\n }\n\n // Required fields - relaxed validation for display-only fields and placeholder types\n const fieldType = field.type as string\n const isPlaceholderType = PLACEHOLDER_FIELD_TYPES.includes(fieldType)\n const isDisplayOnlyType = ['heading', 'notification_bar', 'response_message', 'timeline',\n 'chip', 'status_label', 'loader', 'stepper', 'section_nav', 'tabs',\n 'disclosure', 'accordion_panel', 'information_panel', 'float_area'].includes(fieldType)\n\n // ID is optional for display-only and placeholder types\n if (!isDefined(field.id) && !isDisplayOnlyType && !isPlaceholderType) {\n errors.push({\n type: 'MISSING_REQUIRED_FIELD',\n message: 'Field must have an \"id\"',\n path,\n })\n }\n\n if (!isDefined(field.type)) {\n errors.push({\n type: 'MISSING_REQUIRED_FIELD',\n message: 'Field must have a \"type\"',\n path,\n })\n }\n // Note: We allow placeholder field types that are not yet implemented\n // They will be normalized to 'text' as fallback\n\n // Label is optional for placeholder types (they often have different required fields)\n if (!isDefined(field.label) && !isPlaceholderType) {\n errors.push({\n type: 'MISSING_REQUIRED_FIELD',\n message: 'Field must have a \"label\"',\n path,\n })\n }\n\n // Validate options for select-like fields\n const selectTypes = ['select', 'multi_select', 'radio_group', 'checkbox_group']\n if (selectTypes.includes(field.type as string)) {\n if (!isDefined(field.options)) {\n errors.push({\n type: 'MISSING_REQUIRED_FIELD',\n message: `Field type \"${field.type}\" requires \"options\"`,\n path,\n })\n } else if (!isArray(field.options) && !isString(field.options)) {\n errors.push({\n type: 'INVALID_VALUE',\n message: 'Options must be an array or a reference string',\n path: `${path}.options`,\n })\n } else if (isArray(field.options)) {\n field.options.forEach((option, index) => {\n errors.push(...validateSelectOption(option, `${path}.options[${index}]`))\n })\n }\n }\n\n // Validate repeater item_fields\n if (field.type === 'repeater') {\n if (!isDefined(field.item_fields)) {\n errors.push({\n type: 'MISSING_REQUIRED_FIELD',\n message: 'Repeater field must have \"item_fields\"',\n path,\n })\n } else if (!isArray(field.item_fields)) {\n errors.push({\n type: 'INVALID_VALUE',\n message: 'item_fields must be an array',\n path: `${path}.item_fields`,\n })\n } else {\n (field.item_fields as unknown[]).forEach((itemField, index) => {\n errors.push(...validateInputField(itemField, `${path}.item_fields[${index}]`))\n })\n }\n }\n\n return errors\n}\n\n/**\n * 選択肢をバリデート\n */\nfunction validateSelectOption(\n option: unknown,\n path: string\n): ParseError[] {\n const errors: ParseError[] = []\n\n if (!isObject(option)) {\n errors.push({\n type: 'INVALID_VALUE',\n message: 'Option must be an object',\n path,\n })\n return errors\n }\n\n if (!isDefined(option.value)) {\n errors.push({\n type: 'MISSING_REQUIRED_FIELD',\n message: 'Option must have a \"value\"',\n path,\n })\n }\n\n if (!isDefined(option.label)) {\n errors.push({\n type: 'MISSING_REQUIRED_FIELD',\n message: 'Option must have a \"label\"',\n path,\n })\n }\n\n return errors\n}\n\n/**\n * アクションをバリデート\n */\nfunction validateAction(\n action: unknown,\n path: string\n): ParseError[] {\n const errors: ParseError[] = []\n\n if (!isObject(action)) {\n errors.push({\n type: 'INVALID_VALUE',\n message: 'Action must be an object',\n path,\n })\n return errors\n }\n\n if (!isDefined(action.id)) {\n errors.push({\n type: 'MISSING_REQUIRED_FIELD',\n message: 'Action must have an \"id\"',\n path,\n })\n }\n\n if (!isDefined(action.type)) {\n errors.push({\n type: 'MISSING_REQUIRED_FIELD',\n message: 'Action must have a \"type\"',\n path,\n })\n } else if (!VALID_ACTION_TYPES.includes(action.type as typeof VALID_ACTION_TYPES[number])) {\n errors.push({\n type: 'INVALID_FIELD_TYPE',\n message: `Invalid action type: \"${action.type}\". Valid types are: ${VALID_ACTION_TYPES.join(', ')}`,\n path: `${path}.type`,\n })\n }\n\n if (!isDefined(action.label)) {\n errors.push({\n type: 'MISSING_REQUIRED_FIELD',\n message: 'Action must have a \"label\"',\n path,\n })\n }\n\n // Type-specific validation\n if (action.type === 'navigate' && !isDefined(action.to)) {\n errors.push({\n type: 'MISSING_REQUIRED_FIELD',\n message: 'Navigate action must have a \"to\" destination',\n path,\n })\n }\n\n // Note: handler is optional for custom actions - it can be provided at runtime via callbacks\n // if (action.type === 'custom' && !isDefined(action.handler)) { ... }\n\n return errors\n}\n\n/**\n * ウィザード設定をバリデート\n */\nfunction validateWizard(\n wizard: unknown,\n path: string\n): ParseError[] {\n const errors: ParseError[] = []\n\n if (!isObject(wizard)) {\n errors.push({\n type: 'INVALID_VALUE',\n message: 'Wizard must be an object',\n path,\n })\n return errors\n }\n\n if (!isDefined(wizard.steps)) {\n errors.push({\n type: 'MISSING_REQUIRED_FIELD',\n message: 'Wizard must have \"steps\"',\n path,\n })\n return errors\n }\n\n if (!isArray(wizard.steps)) {\n errors.push({\n type: 'INVALID_VALUE',\n message: 'Wizard steps must be an array',\n path: `${path}.steps`,\n })\n return errors\n }\n\n (wizard.steps as unknown[]).forEach((step, index) => {\n errors.push(...validateWizardStep(step, `${path}.steps[${index}]`))\n })\n\n return errors\n}\n\n/**\n * ウィザードステップをバリデート\n */\nfunction validateWizardStep(\n step: unknown,\n path: string\n): ParseError[] {\n const errors: ParseError[] = []\n\n if (!isObject(step)) {\n errors.push({\n type: 'INVALID_VALUE',\n message: 'Wizard step must be an object',\n path,\n })\n return errors\n }\n\n if (!isDefined(step.id)) {\n errors.push({\n type: 'MISSING_REQUIRED_FIELD',\n message: 'Wizard step must have an \"id\"',\n path,\n })\n }\n\n if (!isDefined(step.title)) {\n errors.push({\n type: 'MISSING_REQUIRED_FIELD',\n message: 'Wizard step must have a \"title\"',\n path,\n })\n }\n\n if (!isDefined(step.fields)) {\n errors.push({\n type: 'MISSING_REQUIRED_FIELD',\n message: 'Wizard step must have \"fields\"',\n path,\n })\n } else if (!isArray(step.fields)) {\n errors.push({\n type: 'INVALID_VALUE',\n message: 'Wizard step fields must be an array',\n path: `${path}.fields`,\n })\n } else {\n (step.fields as unknown[]).forEach((field, index) => {\n errors.push(...validateInputField(field, `${path}.fields[${index}]`))\n })\n }\n\n return errors\n}\n\n/**\n * 画面定義をバリデート\n */\nfunction validateScreenDefinition(\n screen: unknown,\n path: string\n): ParseError[] {\n const errors: ParseError[] = []\n\n if (!isObject(screen)) {\n errors.push({\n type: 'INVALID_VALUE',\n message: 'Screen definition must be an object',\n path,\n })\n return errors\n }\n\n if (!isDefined(screen.title)) {\n errors.push({\n type: 'MISSING_REQUIRED_FIELD',\n message: 'Screen must have a \"title\"',\n path,\n })\n }\n\n // Validate wizard if present\n if (isDefined(screen.wizard)) {\n errors.push(...validateWizard(screen.wizard, `${path}.wizard`))\n }\n\n // Validate fields if present\n if (isDefined(screen.fields)) {\n if (!isArray(screen.fields)) {\n errors.push({\n type: 'INVALID_VALUE',\n message: 'Screen fields must be an array',\n path: `${path}.fields`,\n })\n } else {\n (screen.fields as unknown[]).forEach((field, index) => {\n errors.push(...validateInputField(field, `${path}.fields[${index}]`))\n })\n }\n }\n\n // Validate actions if present\n if (isDefined(screen.actions)) {\n if (!isArray(screen.actions)) {\n errors.push({\n type: 'INVALID_VALUE',\n message: 'Screen actions must be an array',\n path: `${path}.actions`,\n })\n } else {\n (screen.actions as unknown[]).forEach((action, index) => {\n errors.push(...validateAction(action, `${path}.actions[${index}]`))\n })\n }\n }\n\n return errors\n}\n\n/**\n * 共通コンポーネントをバリデート\n */\nfunction validateCommonComponent(\n component: unknown,\n path: string\n): ParseError[] {\n const errors: ParseError[] = []\n\n if (!isObject(component)) {\n errors.push({\n type: 'INVALID_VALUE',\n message: 'Common component must be an object',\n path,\n })\n return errors\n }\n\n if (!isDefined(component.name)) {\n errors.push({\n type: 'MISSING_REQUIRED_FIELD',\n message: 'Common component must have a \"name\"',\n path,\n })\n }\n\n if (!isDefined(component.type)) {\n errors.push({\n type: 'MISSING_REQUIRED_FIELD',\n message: 'Common component must have a \"type\"',\n path,\n })\n } else if (!VALID_COMPONENT_TYPES.includes(component.type as typeof VALID_COMPONENT_TYPES[number])) {\n errors.push({\n type: 'INVALID_FIELD_TYPE',\n message: `Invalid component type: \"${component.type}\". Valid types are: ${VALID_COMPONENT_TYPES.join(', ')}`,\n path: `${path}.type`,\n })\n }\n\n // Validate fields for field_group type\n if (component.type === 'field_group' && isDefined(component.fields)) {\n if (!isArray(component.fields)) {\n errors.push({\n type: 'INVALID_VALUE',\n message: 'Component fields must be an array',\n path: `${path}.fields`,\n })\n } else {\n (component.fields as unknown[]).forEach((field, index) => {\n errors.push(...validateInputField(field, `${path}.fields[${index}]`))\n })\n }\n }\n\n // Validate actions for action_group type\n if (component.type === 'action_group' && isDefined(component.actions)) {\n if (!isArray(component.actions)) {\n errors.push({\n type: 'INVALID_VALUE',\n message: 'Component actions must be an array',\n path: `${path}.actions`,\n })\n } else {\n (component.actions as unknown[]).forEach((action, index) => {\n errors.push(...validateAction(action, `${path}.actions[${index}]`))\n })\n }\n }\n\n return errors\n}\n\n/**\n * バリデーションルールをバリデート\n */\nfunction validateValidationRule(\n rule: unknown,\n path: string\n): ParseError[] {\n const errors: ParseError[] = []\n\n if (!isObject(rule)) {\n errors.push({\n type: 'INVALID_VALUE',\n message: 'Validation rule must be an object',\n path,\n })\n return errors\n }\n\n if (!isDefined(rule.name)) {\n errors.push({\n type: 'MISSING_REQUIRED_FIELD',\n message: 'Validation rule must have a \"name\"',\n path,\n })\n }\n\n if (!isDefined(rule.rules)) {\n errors.push({\n type: 'MISSING_REQUIRED_FIELD',\n message: 'Validation rule must have \"rules\"',\n path,\n })\n }\n\n return errors\n}\n\n/**\n * 配列形式の画面定義をバリデート(緩いバリデーション)\n */\nfunction validateScreenDefinitionArray(\n screen: unknown,\n path: string\n): ParseError[] {\n const errors: ParseError[] = []\n\n if (!isObject(screen)) {\n errors.push({\n type: 'INVALID_VALUE',\n message: 'Screen definition must be an object',\n path,\n })\n return errors\n }\n\n // 配列形式の場合はnameまたはtitleが必須\n if (!isDefined(screen.name) && !isDefined(screen.title)) {\n errors.push({\n type: 'MISSING_REQUIRED_FIELD',\n message: 'Screen must have a \"name\" or \"title\"',\n path,\n })\n }\n\n // セクションがある場合は各セクションをバリデート\n if (isDefined(screen.sections)) {\n if (!isArray(screen.sections)) {\n errors.push({\n type: 'INVALID_VALUE',\n message: 'sections must be an array',\n path: `${path}.sections`,\n })\n }\n // 配列形式のフィールドは緩くバリデート(field_nameベースでもOK)\n }\n\n return errors\n}\n\n/**\n * 配列形式の共通コンポーネントをバリデート\n */\nfunction validateCommonComponentArray(\n component: unknown,\n path: string\n): ParseError[] {\n const errors: ParseError[] = []\n\n if (!isObject(component)) {\n errors.push({\n type: 'INVALID_VALUE',\n message: 'Common component must be an object',\n path,\n })\n return errors\n }\n\n if (!isDefined(component.component_name)) {\n errors.push({\n type: 'MISSING_REQUIRED_FIELD',\n message: 'Common component must have a \"component_name\"',\n path,\n })\n }\n\n return errors\n}\n\n/**\n * 配列形式のバリデーションルールをバリデート\n */\nfunction validateValidationRuleArray(\n rule: unknown,\n path: string\n): ParseError[] {\n const errors: ParseError[] = []\n\n if (!isObject(rule)) {\n errors.push({\n type: 'INVALID_VALUE',\n message: 'Validation rule must be an object',\n path,\n })\n return errors\n }\n\n if (!isDefined(rule.field)) {\n errors.push({\n type: 'MISSING_REQUIRED_FIELD',\n message: 'Validation rule must have a \"field\"',\n path,\n })\n }\n\n if (!isDefined(rule.rule)) {\n errors.push({\n type: 'MISSING_REQUIRED_FIELD',\n message: 'Validation rule must have a \"rule\"',\n path,\n })\n }\n\n return errors\n}\n\n/**\n * スキーマ全体をバリデート(配列形式もサポート)\n */\nfunction validateSchema(data: unknown): ParseError[] {\n const errors: ParseError[] = []\n\n if (!isObject(data)) {\n errors.push({\n type: 'SCHEMA_VALIDATION_ERROR',\n message: 'Root must be an object',\n path: '',\n })\n return errors\n }\n\n // view is required\n if (!isDefined(data.view)) {\n errors.push({\n type: 'MISSING_REQUIRED_FIELD',\n message: 'Schema must have a \"view\" section',\n path: '',\n })\n } else if (isArray(data.view)) {\n // 配列形式のviewをバリデート\n (data.view as unknown[]).forEach((screen, index) => {\n errors.push(...validateScreenDefinitionArray(screen, `view[${index}]`))\n })\n } else if (isObject(data.view)) {\n // オブジェクト形式のviewをバリデート\n for (const [screenName, screen] of Object.entries(data.view)) {\n errors.push(...validateScreenDefinition(screen, `view.${screenName}`))\n }\n } else {\n errors.push({\n type: 'INVALID_VALUE',\n message: '\"view\" must be an object or array',\n path: 'view',\n })\n }\n\n // Validate common_components if present\n if (isDefined(data.common_components)) {\n if (isArray(data.common_components)) {\n // 配列形式\n (data.common_components as unknown[]).forEach((component, index) => {\n errors.push(...validateCommonComponentArray(component, `common_components[${index}]`))\n })\n } else if (isObject(data.common_components)) {\n // オブジェクト形式\n for (const [componentName, component] of Object.entries(data.common_components)) {\n errors.push(...validateCommonComponent(component, `common_components.${componentName}`))\n }\n } else {\n errors.push({\n type: 'INVALID_VALUE',\n message: '\"common_components\" must be an object or array',\n path: 'common_components',\n })\n }\n }\n\n // Validate validations if present\n if (isDefined(data.validations)) {\n if (isArray(data.validations)) {\n // 配列形式\n (data.validations as unknown[]).forEach((rule, index) => {\n errors.push(...validateValidationRuleArray(rule, `validations[${index}]`))\n })\n } else if (isObject(data.validations)) {\n // オブジェクト形式\n for (const [ruleName, rule] of Object.entries(data.validations)) {\n errors.push(...validateValidationRule(rule, `validations.${ruleName}`))\n }\n } else {\n errors.push({\n type: 'INVALID_VALUE',\n message: '\"validations\" must be an object or array',\n path: 'validations',\n })\n }\n }\n\n return errors\n}\n\n// =============================================================================\n// Parser / パーサー\n// =============================================================================\n\n/**\n * YAMLテキストをパースしてMokkunSchemaに変換\n */\nexport function parseYaml(yamlText: string): ParseResult<MokkunSchema> {\n try {\n // Parse YAML\n const data = yaml.load(yamlText)\n\n // Validate schema\n const errors = validateSchema(data)\n\n if (errors.length > 0) {\n return { success: false, errors }\n }\n\n // 正規化(配列形式をオブジェクト形式に変換)\n const normalizedData = normalizeSchema(data as MokkunSchemaRaw)\n\n return { success: true, data: normalizedData }\n } catch (error) {\n if (error instanceof yaml.YAMLException) {\n return {\n success: false,\n errors: [\n {\n type: 'YAML_SYNTAX_ERROR',\n message: error.message,\n line: error.mark?.line,\n column: error.mark?.column,\n },\n ],\n }\n }\n\n return {\n success: false,\n errors: [\n {\n type: 'YAML_SYNTAX_ERROR',\n message: error instanceof Error ? error.message : 'Unknown error',\n },\n ],\n }\n }\n}\n\n/**\n * パースエラーを整形して文字列に変換\n */\nexport function formatParseErrors(errors: ParseError[]): string {\n return errors\n .map((error) => {\n let location = ''\n if (error.path) {\n location = ` at \"${error.path}\"`\n }\n if (error.line !== undefined) {\n location += ` (line ${error.line + 1}`\n if (error.column !== undefined) {\n location += `, column ${error.column + 1}`\n }\n location += ')'\n }\n return `[${error.type}]${location}: ${error.message}`\n })\n .join('\\n')\n}\n\n// =============================================================================\n// Utility Functions / ユーティリティ関数\n// =============================================================================\n\n/**\n * 画面定義を取得\n */\nexport function getScreen(\n schema: MokkunSchema,\n screenName: string\n): ScreenDefinition | undefined {\n return schema.view[screenName]\n}\n\n/**\n * 全ての画面名を取得\n */\nexport function getScreenNames(schema: MokkunSchema): string[] {\n return Object.keys(schema.view)\n}\n\n/**\n * フィールドをIDで検索\n */\nexport function findFieldById(\n fields: InputField[],\n fieldId: string\n): InputField | undefined {\n for (const field of fields) {\n if (field.id === fieldId) {\n return field\n }\n // Repeater内のフィールドも検索\n if (field.type === 'repeater') {\n const found = findFieldById(field.item_fields, fieldId)\n if (found) return found\n }\n }\n return undefined\n}\n\n/**\n * 共通コンポーネントを取得\n */\nexport function getCommonComponent(\n schema: MokkunSchema,\n componentName: string\n): CommonComponent | undefined {\n return schema.common_components?.[componentName]\n}\n\n/**\n * バリデーションルールを取得\n */\nexport function getValidationRule(\n schema: MokkunSchema,\n ruleName: string\n): ValidationRule | undefined {\n return schema.validations?.[ruleName]\n}\n","/**\n * DOM Utilities\n * DOM操作のユーティリティ関数\n */\n\n/**\n * 要素を作成する\n */\nexport function createElement<K extends keyof HTMLElementTagNameMap>(\n tag: K,\n options?: {\n className?: string\n attributes?: Record<string, string>\n textContent?: string\n children?: (HTMLElement | string)[]\n }\n): HTMLElementTagNameMap[K] {\n const element = document.createElement(tag)\n\n if (options?.className) {\n element.className = options.className\n }\n\n if (options?.attributes) {\n for (const [key, value] of Object.entries(options.attributes)) {\n element.setAttribute(key, value)\n }\n }\n\n if (options?.textContent) {\n element.textContent = options.textContent\n }\n\n if (options?.children) {\n for (const child of options.children) {\n if (typeof child === 'string') {\n element.appendChild(document.createTextNode(child))\n } else {\n element.appendChild(child)\n }\n }\n }\n\n return element\n}\n\n/**\n * 要素をクリアする\n */\nexport function clearElement(element: HTMLElement): void {\n while (element.firstChild) {\n element.removeChild(element.firstChild)\n }\n}\n\n/**\n * 一意なIDを生成する\n */\nexport function generateId(prefix: string = 'mokkun'): string {\n return `${prefix}-${Date.now()}-${Math.random().toString(36).substring(2, 9)}`\n}\n\n/**\n * HTMLテキストをエスケープする\n */\nexport function escapeHtml(text: string): string {\n const div = document.createElement('div')\n div.textContent = text\n return div.innerHTML\n}\n\n/**\n * タブIDを検証・サニタイズする\n */\nexport function sanitizeTabId(id: string): string {\n // 英数字、ハイフン、アンダースコアのみ許可\n return id.replace(/[^a-zA-Z0-9_-]/g, '')\n}\n","/**\n * Field Helper Utilities\n * フォームフィールドレンダリング用の共有ヘルパー関数\n */\n\nimport type { InputField, SelectOption } from '../../types/schema'\n\n/**\n * HTML特殊文字をエスケープ\n *\n * @param text - エスケープする文字列\n * @returns エスケープされた文字列\n */\nexport function escapeHtml(text: string): string {\n const div = document.createElement('div')\n div.textContent = text\n return div.innerHTML\n}\n\n/**\n * SSR対応のHTMLエスケープ\n * document が利用できない環境でも動作する\n *\n * @param text - エスケープする文字列\n * @returns エスケープされた文字列\n */\nexport function escapeHtmlSafe(text: string): string {\n if (typeof document !== 'undefined') {\n return escapeHtml(text)\n }\n // SSR環境用のフォールバック\n return text\n .replace(/&/g, '&amp;')\n .replace(/</g, '&lt;')\n .replace(/>/g, '&gt;')\n .replace(/\"/g, '&quot;')\n .replace(/'/g, '&#039;')\n}\n\n/**\n * フィールドのラッパーHTML生成\n *\n * @param field - 入力フィールド定義\n * @param content - フィールドのコンテンツHTML\n * @returns ラッパー付きのHTML文字列\n */\nexport function createFieldWrapper(field: InputField, content: string): string {\n const requiredMark = field.required ? '<span class=\"required-mark\">*</span>' : ''\n const description = field.description\n ? `<p class=\"field-description\">${escapeHtml(field.description)}</p>`\n : ''\n const classes = ['form-field', `field-type-${field.type}`]\n if (field.class) {\n classes.push(field.class)\n }\n\n // visible_when 条件をdata属性に埋め込む\n const visibleWhenAttr = field.visible_when\n ? ` data-visible-when=\"${escapeHtml(JSON.stringify(field.visible_when))}\"`\n : ''\n\n return `\n <div class=\"${classes.join(' ')}\" data-field-id=\"${escapeHtml(field.id)}\"${visibleWhenAttr}>\n <label class=\"field-label\" for=\"${escapeHtml(field.id)}\">\n ${escapeHtml(field.label)}${requiredMark}\n </label>\n ${content}\n ${description}\n </div>\n `\n}\n\n/**\n * 共通属性を生成\n *\n * @param field - 入力フィールド定義\n * @returns 属性文字列\n */\nexport function getCommonAttributes(field: InputField): string {\n const attrs: string[] = [\n `id=\"${escapeHtml(field.id)}\"`,\n `name=\"${escapeHtml(field.id)}\"`,\n ]\n\n if (field.required) {\n attrs.push('required')\n }\n if (field.disabled) {\n attrs.push('disabled')\n }\n if (field.readonly) {\n attrs.push('readonly')\n }\n if ('placeholder' in field && field.placeholder) {\n attrs.push(`placeholder=\"${escapeHtml(field.placeholder)}\"`)\n }\n\n return attrs.join(' ')\n}\n\n/**\n * 選択肢の配列を取得(文字列参照は未対応)\n *\n * @param options - 選択肢配列または参照文字列\n * @returns 選択肢の配列\n */\nexport function getOptions(options: SelectOption[] | string): SelectOption[] {\n if (typeof options === 'string') {\n // 共通コンポーネント参照は未対応(Phase 3以降で対応予定)\n return []\n }\n return options\n}\n\n/**\n * ファイルサイズをフォーマット\n *\n * @param bytes - バイト数\n * @returns フォーマットされたサイズ文字列\n */\nexport function formatFileSize(bytes: number): string {\n if (bytes < 1024) {\n return `${bytes} B`\n }\n if (bytes < 1024 * 1024) {\n return `${(bytes / 1024).toFixed(1)} KB`\n }\n return `${(bytes / (1024 * 1024)).toFixed(1)} MB`\n}\n\n/**\n * MIMEタイプから表示名を取得\n *\n * @param mimeType - MIMEタイプ文字列\n * @returns 表示用のフォーマット名\n */\nexport function formatMimeType(mimeType: string): string {\n const formats: Record<string, string> = {\n 'image/jpeg': 'JPEG',\n 'image/png': 'PNG',\n 'image/webp': 'WebP',\n 'image/gif': 'GIF',\n }\n return formats[mimeType] ?? mimeType\n}\n\n/**\n * レベルに基づくデフォルトサイズを取得\n *\n * @param level - 見出しレベル (1-6)\n * @returns サイズバリアント\n */\nexport function getDefaultSizeForLevel(\n level: 1 | 2 | 3 | 4 | 5 | 6\n): 'xs' | 'sm' | 'md' | 'lg' | 'xl' | '2xl' {\n const sizeMap: Record<number, 'xs' | 'sm' | 'md' | 'lg' | 'xl' | '2xl'> = {\n 1: '2xl',\n 2: 'xl',\n 3: 'lg',\n 4: 'md',\n 5: 'sm',\n 6: 'xs',\n }\n return sizeMap[level]\n}\n\n/**\n * 単位ラベルのマッピング\n */\nexport const unitLabels: Record<string, string> = {\n days: '日',\n hours: '時間',\n minutes: '分',\n seconds: '秒',\n}\n","/**\n * Input Component\n * 汎用テキスト入力コンポーネント\n *\n * Features:\n * - Prefix/Suffix support\n * - Validation display\n * - Size variants (small/medium/large)\n * - Input types (text/email/password/number/tel/url)\n * - Clear button\n * - Error states\n */\n\nimport { createElement, generateId } from '../utils/dom'\nimport {\n escapeHtml,\n createFieldWrapper,\n getCommonAttributes,\n} from '../utils/field-helpers'\nimport type { TextField, NumberField, DatePickerField, TimePickerField } from '../../types/schema'\n\n// =============================================================================\n// Types\n// =============================================================================\n\n/**\n * 入力の状態\n */\nexport interface InputState {\n /** 現在の値 */\n value: string\n /** 無効化状態 */\n disabled: boolean\n /** 読み取り専用状態 */\n readonly: boolean\n /** エラー状態 */\n error: boolean\n /** エラーメッセージ */\n errorMessage?: string\n /** フォーカス状態 */\n focused: boolean\n}\n\n/**\n * 入力のコールバック\n */\nexport interface InputCallbacks {\n /** 値変更時 */\n onChange?: (value: string, state: InputState) => void\n /** フォーカス時 */\n onFocus?: (state: InputState) => void\n /** ブラー時 */\n onBlur?: (state: InputState) => void\n /** クリアボタン押下時 */\n onClear?: (state: InputState) => void\n /** Enter キー押下時 */\n onEnter?: (value: string, state: InputState) => void\n}\n\n/**\n * 入力の設定\n */\nexport interface InputConfig {\n /** 初期値 */\n defaultValue?: string\n /** プレースホルダー */\n placeholder?: string\n /** 無効化 */\n disabled?: boolean\n /** 読み取り専用 */\n readonly?: boolean\n /** 必須 */\n required?: boolean\n /** サイズ */\n size?: 'small' | 'medium' | 'large'\n /** 入力タイプ */\n type?: 'text' | 'email' | 'password' | 'number' | 'tel' | 'url'\n /** name属性(フォーム用) */\n name?: string\n /** プレフィックス(アイコンやテキスト) */\n prefix?: string | HTMLElement\n /** サフィックス(アイコンやテキスト) */\n suffix?: string | HTMLElement\n /** クリアボタン表示 */\n clearable?: boolean\n /** 自動フォーカス */\n autoFocus?: boolean\n /** オートコンプリート */\n autoComplete?: string\n /** エラーメッセージ(初期値) */\n errorMessage?: string\n /** aria-label */\n ariaLabel?: string\n /** aria-describedby */\n ariaDescribedBy?: string\n}\n\n// =============================================================================\n// Input Class\n// =============================================================================\n\n/**\n * 入力コンポーネント\n */\nexport class Input {\n private config: InputConfig\n private state: InputState\n private callbacks: InputCallbacks\n private container: HTMLElement\n private instanceId: string\n private inputElement: HTMLInputElement | null = null\n\n constructor(\n container: HTMLElement,\n config: InputConfig = {},\n callbacks: InputCallbacks = {}\n ) {\n this.config = config\n this.container = container\n this.callbacks = callbacks\n this.instanceId = generateId('input')\n this.state = this.createInitialState()\n }\n\n // ===========================================================================\n // Public Methods\n // ===========================================================================\n\n /**\n * 入力フィールドをレンダリング\n */\n render(): void {\n this.container.innerHTML = ''\n\n const size = this.config.size ?? 'medium'\n const hasPrefix = !!this.config.prefix\n const hasSuffix = !!this.config.suffix || !!this.config.clearable\n\n this.container.className = `mokkun-input input-${size}`\n\n // data-state属性を設定\n this.container.setAttribute('data-state', this.getDataState())\n if (this.state.disabled) {\n this.container.setAttribute('data-disabled', '')\n } else {\n this.container.removeAttribute('data-disabled')\n }\n if (this.state.readonly) {\n this.container.setAttribute('data-readonly', '')\n } else {\n this.container.removeAttribute('data-readonly')\n }\n if (this.state.error) {\n this.container.setAttribute('data-error', '')\n } else {\n this.container.removeAttribute('data-error')\n }\n\n const wrapper = createElement('div', { className: 'input-wrapper' })\n\n // 入力グループ(prefix + input + suffix/clear)\n const inputGroup = this.renderInputGroup(hasPrefix, hasSuffix)\n wrapper.appendChild(inputGroup)\n\n // エラーメッセージ\n if (this.state.error && this.state.errorMessage) {\n const errorElement = this.renderError()\n wrapper.appendChild(errorElement)\n }\n\n this.container.appendChild(wrapper)\n\n // オートフォーカス\n if (this.config.autoFocus && this.inputElement) {\n this.inputElement.focus()\n }\n }\n\n /**\n * 値を設定\n */\n setValue(value: string): void {\n if (this.state.value === value) {\n return\n }\n\n this.state = {\n ...this.state,\n value,\n }\n\n if (this.inputElement) {\n this.inputElement.value = value\n }\n\n this.callbacks.onChange?.(value, this.state)\n }\n\n /**\n * 値を取得\n */\n getValue(): string {\n return this.state.value\n }\n\n /**\n * エラー状態を設定\n */\n setError(error: boolean, errorMessage?: string): void {\n this.state = {\n ...this.state,\n error,\n errorMessage,\n }\n\n this.render()\n }\n\n /**\n * 無効化状態を設定\n */\n setDisabled(disabled: boolean): void {\n if (this.state.disabled === disabled) {\n return\n }\n\n this.state = {\n ...this.state,\n disabled,\n }\n\n this.render()\n }\n\n /**\n * 読み取り専用状態を設定\n */\n setReadonly(readonly: boolean): void {\n if (this.state.readonly === readonly) {\n return\n }\n\n this.state = {\n ...this.state,\n readonly,\n }\n\n this.render()\n }\n\n /**\n * フォーカス\n */\n focus(): void {\n if (this.inputElement) {\n this.inputElement.focus()\n }\n }\n\n /**\n * ブラー\n */\n blur(): void {\n if (this.inputElement) {\n this.inputElement.blur()\n }\n }\n\n /**\n * クリア\n */\n clear(): void {\n this.setValue('')\n this.callbacks.onClear?.(this.state)\n this.focus()\n }\n\n /**\n * 状態を取得\n */\n getState(): InputState {\n return { ...this.state }\n }\n\n /**\n * 破棄\n */\n destroy(): void {\n this.container.innerHTML = ''\n }\n\n // ===========================================================================\n // Private Methods\n // ===========================================================================\n\n /**\n * 初期状態を作成\n */\n private createInitialState(): InputState {\n return {\n value: this.config.defaultValue ?? '',\n disabled: this.config.disabled ?? false,\n readonly: this.config.readonly ?? false,\n error: !!this.config.errorMessage,\n errorMessage: this.config.errorMessage,\n focused: false,\n }\n }\n\n /**\n * data-state属性の値を取得\n */\n private getDataState(): string {\n if (this.state.error) return 'error'\n if (this.state.focused) return 'focused'\n if (this.state.value) return 'filled'\n return 'empty'\n }\n\n /**\n * 入力グループをレンダリング\n */\n private renderInputGroup(hasPrefix: boolean, hasSuffix: boolean): HTMLElement {\n const inputGroup = createElement('div', {\n className: `input-group ${hasPrefix ? 'has-prefix' : ''} ${hasSuffix ? 'has-suffix' : ''}`\n })\n\n // Prefix\n if (hasPrefix && this.config.prefix) {\n const prefixElement = this.renderAffix(this.config.prefix, 'prefix')\n inputGroup.appendChild(prefixElement)\n }\n\n // Input\n const input = this.renderInput()\n inputGroup.appendChild(input)\n\n // Suffix or Clear button\n if (hasSuffix) {\n if (this.config.clearable && this.state.value && !this.state.disabled && !this.state.readonly) {\n const clearButton = this.renderClearButton()\n inputGroup.appendChild(clearButton)\n } else if (this.config.suffix) {\n const suffixElement = this.renderAffix(this.config.suffix, 'suffix')\n inputGroup.appendChild(suffixElement)\n }\n }\n\n return inputGroup\n }\n\n /**\n * 入力フィールドをレンダリング\n */\n private renderInput(): HTMLInputElement {\n const input = createElement('input', {\n className: 'input-field',\n attributes: {\n type: this.config.type ?? 'text',\n id: this.instanceId,\n ...(this.config.name && { name: this.config.name }),\n ...(this.config.placeholder && { placeholder: this.config.placeholder }),\n ...(this.config.required && { required: 'required' }),\n ...(this.config.autoComplete && { autocomplete: this.config.autoComplete }),\n ...(this.config.ariaLabel && { 'aria-label': this.config.ariaLabel }),\n ...(this.config.ariaDescribedBy && { 'aria-describedby': this.config.ariaDescribedBy }),\n ...(this.state.disabled && { disabled: 'disabled' }),\n ...(this.state.readonly && { readonly: 'readonly' }),\n ...(this.state.error && { 'aria-invalid': 'true' }),\n },\n })\n\n input.value = this.state.value\n\n // イベントリスナー\n input.addEventListener('input', this.handleInput.bind(this))\n input.addEventListener('focus', this.handleFocus.bind(this))\n input.addEventListener('blur', this.handleBlur.bind(this))\n input.addEventListener('keydown', this.handleKeyDown.bind(this))\n\n this.inputElement = input\n return input\n }\n\n /**\n * Prefix/Suffixをレンダリング\n */\n private renderAffix(affix: string | HTMLElement, type: 'prefix' | 'suffix'): HTMLElement {\n const affixWrapper = createElement('span', { className: `input-${type}` })\n\n if (typeof affix === 'string') {\n affixWrapper.textContent = affix\n } else {\n affixWrapper.appendChild(affix)\n }\n\n return affixWrapper\n }\n\n /**\n * クリアボタンをレンダリング\n */\n private renderClearButton(): HTMLElement {\n const button = createElement('button', {\n className: 'input-clear-button',\n attributes: {\n type: 'button',\n 'aria-label': 'Clear input',\n },\n })\n\n // クリアアイコン (×)\n const icon = createElement('span', {\n className: 'clear-icon',\n textContent: '×',\n })\n button.appendChild(icon)\n\n button.addEventListener('click', this.handleClear.bind(this))\n\n return button\n }\n\n /**\n * エラーメッセージをレンダリング\n */\n private renderError(): HTMLElement {\n return createElement('div', {\n className: 'input-error-message',\n attributes: {\n id: `${this.instanceId}-error`,\n role: 'alert',\n },\n textContent: this.state.errorMessage ?? '',\n })\n }\n\n // ===========================================================================\n // Event Handlers\n // ===========================================================================\n\n /**\n * 入力イベント\n */\n private handleInput(event: Event): void {\n const target = event.target as HTMLInputElement\n const value = target.value\n\n this.state = {\n ...this.state,\n value,\n }\n\n this.callbacks.onChange?.(value, this.state)\n\n // クリアボタンの表示/非表示を更新(DOMを部分的に更新)\n if (this.config.clearable) {\n this.updateClearButton()\n }\n }\n\n /**\n * クリアボタンの表示/非表示を更新(フォーカスを失わないように部分更新)\n */\n private updateClearButton(): void {\n const inputGroup = this.container.querySelector('.input-group')\n if (!inputGroup) return\n\n const existingClearButton = inputGroup.querySelector('.input-clear-button')\n const existingSuffix = inputGroup.querySelector('.input-suffix')\n const shouldShowClear = this.state.value && !this.state.disabled && !this.state.readonly\n\n if (shouldShowClear && !existingClearButton) {\n // クリアボタンを追加\n if (existingSuffix) {\n existingSuffix.remove()\n }\n const clearButton = this.renderClearButton()\n inputGroup.appendChild(clearButton)\n } else if (!shouldShowClear && existingClearButton) {\n // クリアボタンを削除\n existingClearButton.remove()\n // サフィックスがあれば復元\n if (this.config.suffix) {\n const suffixElement = this.renderAffix(this.config.suffix, 'suffix')\n inputGroup.appendChild(suffixElement)\n }\n }\n }\n\n /**\n * フォーカスイベント\n */\n private handleFocus(): void {\n this.state = {\n ...this.state,\n focused: true,\n }\n\n this.container.setAttribute('data-state', this.getDataState())\n this.callbacks.onFocus?.(this.state)\n }\n\n /**\n * ブラーイベント\n */\n private handleBlur(): void {\n this.state = {\n ...this.state,\n focused: false,\n }\n\n this.container.setAttribute('data-state', this.getDataState())\n this.callbacks.onBlur?.(this.state)\n }\n\n /**\n * キーダウンイベント\n */\n private handleKeyDown(event: KeyboardEvent): void {\n if (event.key === 'Enter') {\n this.callbacks.onEnter?.(this.state.value, this.state)\n }\n }\n\n /**\n * クリアイベント\n */\n private handleClear(): void {\n this.clear()\n }\n\n // ===========================================================================\n // Static Field Renderers\n // ===========================================================================\n\n /**\n * 入力フィールドをHTMLとしてレンダリング(静的メソッド)\n * SSR/初期レンダリング用\n *\n * @param field - 入力フィールド定義(text, number, date_picker, time_picker)\n * @returns 生成されたHTML文字列\n */\n static renderField(field: TextField | NumberField | DatePickerField | TimePickerField): string {\n switch (field.type) {\n case 'text':\n return Input.renderTextField(field)\n case 'number':\n return Input.renderNumberField(field)\n case 'date_picker':\n return Input.renderDatePickerField(field)\n case 'time_picker':\n return Input.renderTimePickerField(field)\n default:\n return ''\n }\n }\n\n /**\n * テキストフィールドをHTMLとしてレンダリング(静的メソッド)\n * @internal renderFieldから呼び出される内部メソッド\n */\n private static renderTextField(field: TextField): string {\n const inputType = field.input_type ?? 'text'\n const attrs: string[] = [getCommonAttributes(field)]\n\n if (field.min_length !== undefined) {\n attrs.push(`minlength=\"${field.min_length}\"`)\n }\n if (field.max_length !== undefined) {\n attrs.push(`maxlength=\"${field.max_length}\"`)\n }\n if (field.pattern) {\n attrs.push(`pattern=\"${escapeHtml(field.pattern)}\"`)\n }\n if (field.default !== undefined) {\n attrs.push(`value=\"${escapeHtml(String(field.default))}\"`)\n }\n\n const input = `<input type=\"${inputType}\" class=\"form-input\" ${attrs.join(' ')} />`\n return createFieldWrapper(field, input)\n }\n\n /**\n * 数値フィールドをHTMLとしてレンダリング(静的メソッド)\n * @internal renderFieldから呼び出される内部メソッド\n */\n private static renderNumberField(field: NumberField): string {\n const attrs: string[] = [getCommonAttributes(field)]\n\n if (field.min !== undefined) {\n attrs.push(`min=\"${field.min}\"`)\n }\n if (field.max !== undefined) {\n attrs.push(`max=\"${field.max}\"`)\n }\n if (field.step !== undefined) {\n attrs.push(`step=\"${field.step}\"`)\n }\n if (field.default !== undefined) {\n attrs.push(`value=\"${field.default}\"`)\n }\n\n let input = `<input type=\"number\" class=\"form-input\" ${attrs.join(' ')} />`\n\n if (field.unit) {\n input = `\n <div class=\"input-with-unit\">\n ${input}\n <span class=\"input-unit\">${escapeHtml(field.unit)}</span>\n </div>\n `\n }\n\n return createFieldWrapper(field, input)\n }\n\n /**\n * 日付選択フィールドをHTMLとしてレンダリング(静的メソッド)\n * @internal renderFieldから呼び出される内部メソッド\n */\n private static renderDatePickerField(field: DatePickerField): string {\n const inputType = field.include_time ? 'datetime-local' : 'date'\n const attrs: string[] = [getCommonAttributes(field)]\n\n if (field.min_date) {\n attrs.push(`min=\"${escapeHtml(field.min_date)}\"`)\n }\n if (field.max_date) {\n attrs.push(`max=\"${escapeHtml(field.max_date)}\"`)\n }\n if (field.default !== undefined) {\n attrs.push(`value=\"${escapeHtml(String(field.default))}\"`)\n }\n\n const input = `<input type=\"${inputType}\" class=\"form-input\" ${attrs.join(' ')} />`\n return createFieldWrapper(field, input)\n }\n\n /**\n * 時間選択フィールドをHTMLとしてレンダリング(静的メソッド)\n * @internal renderFieldから呼び出される内部メソッド\n */\n private static renderTimePickerField(field: TimePickerField): string {\n const attrs: string[] = [getCommonAttributes(field)]\n\n if (field.minute_step) {\n attrs.push(`step=\"${field.minute_step * 60}\"`)\n }\n if (field.default !== undefined) {\n attrs.push(`value=\"${escapeHtml(String(field.default))}\"`)\n }\n\n const input = `<input type=\"time\" class=\"form-input\" ${attrs.join(' ')} />`\n return createFieldWrapper(field, input)\n }\n}\n\n// =============================================================================\n// Factory Function\n// =============================================================================\n\n/**\n * 入力コンポーネントを作成\n */\nexport function createInput(\n container: HTMLElement,\n config: InputConfig = {},\n callbacks: InputCallbacks = {}\n): Input {\n const input = new Input(container, config, callbacks)\n input.render()\n return input\n}\n","/**\n * Textarea Component\n * 複数行テキスト入力コンポーネント\n *\n * 機能:\n * - 自動リサイズ\n * - 文字数カウント\n * - 最大文字数制限\n * - 行数指定\n * - バリデーション表示\n *\n * 参考: https://smarthr.design/products/components/textarea/\n */\n\nimport { createElement, generateId } from '../utils/dom'\nimport {\n escapeHtml,\n createFieldWrapper,\n getCommonAttributes,\n} from '../utils/field-helpers'\nimport type { TextareaField } from '../../types/schema'\n\n// =============================================================================\n// Types\n// =============================================================================\n\n/**\n * Textareaの状態\n */\nexport interface TextareaState {\n /** 現在の値 */\n value: string\n /** 無効化状態 */\n disabled: boolean\n /** 読み取り専用状態 */\n readonly: boolean\n /** エラー状態 */\n error: boolean\n /** エラーメッセージ */\n errorMessage?: string\n /** 文字数 */\n characterCount: number\n}\n\n/**\n * Textareaのコールバック\n */\nexport interface TextareaCallbacks {\n /** 値変更時 */\n onChange?: (value: string, state: TextareaState) => void\n /** 入力時 */\n onInput?: (value: string, state: TextareaState) => void\n /** フォーカス時 */\n onFocus?: (state: TextareaState) => void\n /** ブラー時 */\n onBlur?: (state: TextareaState) => void\n}\n\n/**\n * Textareaの設定\n */\nexport interface TextareaConfig {\n /** 初期値 */\n defaultValue?: string\n /** プレースホルダー */\n placeholder?: string\n /** 行数 */\n rows?: number\n /** 最小文字数 */\n minLength?: number\n /** 最大文字数 */\n maxLength?: number\n /** 必須フィールド */\n required?: boolean\n /** 無効化 */\n disabled?: boolean\n /** 読み取り専用 */\n readonly?: boolean\n /** 自動リサイズ */\n autoResize?: boolean\n /** 文字数カウント表示 */\n showCount?: boolean\n /** リサイズ可能 */\n resizable?: boolean\n /** name属性(フォーム用) */\n name?: string\n /** ID */\n id?: string\n /** エラーメッセージ */\n errorMessage?: string\n}\n\n// =============================================================================\n// Textarea Class\n// =============================================================================\n\n/**\n * Textareaコンポーネント\n */\nexport class Textarea {\n private config: TextareaConfig\n private state: TextareaState\n private callbacks: TextareaCallbacks\n private container: HTMLElement\n private textareaElement?: HTMLTextAreaElement\n private instanceId: string\n\n constructor(\n container: HTMLElement,\n config: TextareaConfig = {},\n callbacks: TextareaCallbacks = {}\n ) {\n this.config = config\n this.container = container\n this.callbacks = callbacks\n this.instanceId = config.id ?? generateId('textarea')\n this.state = this.createInitialState()\n }\n\n // ===========================================================================\n // Public Methods\n // ===========================================================================\n\n /**\n * Textareaをレンダリング\n */\n render(): void {\n this.container.innerHTML = ''\n\n const wrapper = createElement('div', {\n className: 'mokkun-textarea-wrapper',\n })\n\n // エラー状態のクラス\n if (this.state.error) {\n wrapper.classList.add('has-error')\n }\n if (this.state.disabled) {\n wrapper.classList.add('is-disabled')\n }\n if (this.state.readonly) {\n wrapper.classList.add('is-readonly')\n }\n\n // Textareaエレメント\n const textarea = this.renderTextarea()\n wrapper.appendChild(textarea)\n\n // 文字数カウント\n if (this.config.showCount) {\n const counter = this.renderCounter()\n wrapper.appendChild(counter)\n }\n\n // エラーメッセージ\n if (this.state.error && this.state.errorMessage) {\n const errorEl = this.renderError()\n wrapper.appendChild(errorEl)\n }\n\n this.container.appendChild(wrapper)\n }\n\n /**\n * 値を設定\n */\n setValue(value: string): void {\n if (this.state.value === value) {\n return\n }\n\n this.state = {\n ...this.state,\n value,\n characterCount: value.length,\n }\n\n if (this.textareaElement) {\n this.textareaElement.value = value\n if (this.config.autoResize) {\n this.adjustHeight()\n }\n }\n\n this.render()\n this.callbacks.onChange?.(value, this.state)\n }\n\n /**\n * 値を取得\n */\n getValue(): string {\n return this.state.value\n }\n\n /**\n * 無効化状態を設定\n */\n setDisabled(disabled: boolean): void {\n if (this.state.disabled === disabled) {\n return\n }\n\n this.state = {\n ...this.state,\n disabled,\n }\n\n this.render()\n }\n\n /**\n * 読み取り専用状態を設定\n */\n setReadonly(readonly: boolean): void {\n if (this.state.readonly === readonly) {\n return\n }\n\n this.state = {\n ...this.state,\n readonly,\n }\n\n this.render()\n }\n\n /**\n * エラー状態を設定\n */\n setError(error: boolean, errorMessage?: string): void {\n if (this.state.error === error && this.state.errorMessage === errorMessage) {\n return\n }\n\n this.state = {\n ...this.state,\n error,\n errorMessage,\n }\n\n this.render()\n }\n\n /**\n * クリア\n */\n clear(): void {\n this.setValue('')\n }\n\n /**\n * フォーカス\n */\n focus(): void {\n this.textareaElement?.focus()\n }\n\n /**\n * ブラー\n */\n blur(): void {\n this.textareaElement?.blur()\n }\n\n /**\n * バリデーション実行\n */\n validate(): boolean {\n const value = this.state.value\n\n // 必須チェック\n if (this.config.required && !value.trim()) {\n this.setError(true, 'この項目は必須です')\n return false\n }\n\n // 最小文字数チェック\n if (this.config.minLength !== undefined && value.length < this.config.minLength) {\n this.setError(true, `${this.config.minLength}文字以上入力してください`)\n return false\n }\n\n // 最大文字数チェック\n if (this.config.maxLength !== undefined && value.length > this.config.maxLength) {\n this.setError(true, `${this.config.maxLength}文字以内で入力してください`)\n return false\n }\n\n this.setError(false)\n return true\n }\n\n /**\n * 現在の状態を取得\n */\n getState(): TextareaState {\n return { ...this.state }\n }\n\n // ===========================================================================\n // Private Methods\n // ===========================================================================\n\n /**\n * 初期状態を作成\n */\n private createInitialState(): TextareaState {\n const value = this.config.defaultValue ?? ''\n return {\n value,\n disabled: this.config.disabled ?? false,\n readonly: this.config.readonly ?? false,\n error: false,\n errorMessage: this.config.errorMessage,\n characterCount: value.length,\n }\n }\n\n /**\n * Textareaエレメントをレンダリング\n */\n private renderTextarea(): HTMLTextAreaElement {\n const rows = this.config.rows ?? 3\n const resizableClass = this.config.resizable === false ? 'no-resize' : ''\n\n const textarea = createElement('textarea', {\n className: `mokkun-textarea ${resizableClass}`,\n attributes: {\n id: this.instanceId,\n rows: String(rows),\n 'aria-label': 'Textarea',\n },\n }) as HTMLTextAreaElement\n\n if (this.config.name) {\n textarea.setAttribute('name', this.config.name)\n }\n\n if (this.config.placeholder) {\n textarea.setAttribute('placeholder', this.config.placeholder)\n }\n\n if (this.config.minLength !== undefined) {\n textarea.setAttribute('minlength', String(this.config.minLength))\n }\n\n if (this.config.maxLength !== undefined) {\n textarea.setAttribute('maxlength', String(this.config.maxLength))\n }\n\n if (this.config.required) {\n textarea.setAttribute('required', 'required')\n textarea.setAttribute('aria-required', 'true')\n }\n\n if (this.state.disabled) {\n textarea.setAttribute('disabled', 'disabled')\n textarea.setAttribute('aria-disabled', 'true')\n }\n\n if (this.state.readonly) {\n textarea.setAttribute('readonly', 'readonly')\n textarea.setAttribute('aria-readonly', 'true')\n }\n\n if (this.state.error) {\n textarea.setAttribute('aria-invalid', 'true')\n if (this.state.errorMessage) {\n textarea.setAttribute('aria-describedby', `${this.instanceId}-error`)\n }\n }\n\n textarea.value = this.state.value\n\n // イベントリスナー\n textarea.addEventListener('input', (e) => {\n const target = e.target as HTMLTextAreaElement\n const value = target.value\n\n this.state = {\n ...this.state,\n value,\n characterCount: value.length,\n }\n\n if (this.config.autoResize) {\n this.adjustHeight()\n }\n\n if (this.config.showCount) {\n this.updateCounter()\n }\n\n this.callbacks.onInput?.(value, this.state)\n })\n\n textarea.addEventListener('change', (e) => {\n const target = e.target as HTMLTextAreaElement\n const value = target.value\n\n this.callbacks.onChange?.(value, this.state)\n })\n\n textarea.addEventListener('focus', () => {\n this.callbacks.onFocus?.(this.state)\n })\n\n textarea.addEventListener('blur', () => {\n this.callbacks.onBlur?.(this.state)\n this.validate()\n })\n\n this.textareaElement = textarea\n\n if (this.config.autoResize) {\n // 初期高さ調整\n setTimeout(() => this.adjustHeight(), 0)\n }\n\n return textarea\n }\n\n /**\n * 文字数カウンターをレンダリング\n */\n private renderCounter(): HTMLElement {\n const counter = createElement('div', {\n className: 'mokkun-textarea-counter',\n attributes: {\n id: `${this.instanceId}-counter`,\n 'aria-live': 'polite',\n },\n })\n\n this.updateCounterContent(counter)\n\n return counter\n }\n\n /**\n * カウンターの内容を更新\n */\n private updateCounterContent(counter: HTMLElement): void {\n const { characterCount } = this.state\n const { maxLength } = this.config\n\n if (maxLength !== undefined) {\n counter.textContent = `${characterCount} / ${maxLength}`\n if (characterCount > maxLength) {\n counter.classList.add('over-limit')\n } else {\n counter.classList.remove('over-limit')\n }\n } else {\n counter.textContent = `${characterCount}文字`\n }\n }\n\n /**\n * カウンターを更新\n */\n private updateCounter(): void {\n const counter = this.container.querySelector(`#${this.instanceId}-counter`)\n if (counter instanceof HTMLElement) {\n this.updateCounterContent(counter)\n }\n }\n\n /**\n * エラーメッセージをレンダリング\n */\n private renderError(): HTMLElement {\n return createElement('div', {\n className: 'mokkun-textarea-error',\n textContent: this.state.errorMessage ?? '',\n attributes: {\n id: `${this.instanceId}-error`,\n role: 'alert',\n 'aria-live': 'polite',\n },\n })\n }\n\n /**\n * 自動リサイズ - 高さ調整\n */\n private adjustHeight(): void {\n if (!this.textareaElement) {\n return\n }\n\n // 一時的にheightをautoにしてscrollHeightを取得\n this.textareaElement.style.height = 'auto'\n const scrollHeight = this.textareaElement.scrollHeight\n this.textareaElement.style.height = `${scrollHeight}px`\n }\n\n // ===========================================================================\n // Static Field Renderer\n // ===========================================================================\n\n /**\n * テキストエリアフィールドをHTMLとしてレンダリング(静的メソッド)\n * SSR/初期レンダリング用\n *\n * @param field - テキストエリアフィールド定義\n * @returns 生成されたHTML文字列\n */\n static renderField(field: TextareaField): string {\n const attrs: string[] = [getCommonAttributes(field)]\n\n if (field.rows) {\n attrs.push(`rows=\"${field.rows}\"`)\n }\n if (field.min_length !== undefined) {\n attrs.push(`minlength=\"${field.min_length}\"`)\n }\n if (field.max_length !== undefined) {\n attrs.push(`maxlength=\"${field.max_length}\"`)\n }\n\n const resizeClass = field.resizable === false ? 'no-resize' : ''\n const defaultValue = field.default !== undefined ? escapeHtml(String(field.default)) : ''\n\n const textarea = `<textarea class=\"form-textarea ${resizeClass}\" ${attrs.join(' ')}>${defaultValue}</textarea>`\n return createFieldWrapper(field, textarea)\n }\n}\n\n// =============================================================================\n// Factory Function\n// =============================================================================\n\n/**\n * Textareaを作成するファクトリ関数\n */\nexport function createTextarea(\n container: HTMLElement,\n config: TextareaConfig = {},\n callbacks: TextareaCallbacks = {}\n): Textarea {\n const textarea = new Textarea(container, config, callbacks)\n textarea.render()\n return textarea\n}\n","/**\n * Select Component\n * セレクトコンポーネント\n *\n * Native <select> based component:\n * - Size variants: 's' | 'default'\n * - State variants: default, disabled, error\n * - Support for optgroup (option grouping)\n * - Placeholder and blank options\n * - Full accessibility with ARIA attributes\n */\n\nimport { createElement, generateId } from '../utils/dom'\nimport {\n escapeHtml,\n createFieldWrapper,\n getCommonAttributes,\n getOptions,\n} from '../utils/field-helpers'\nimport type {\n SelectConfig,\n SelectState,\n SelectCallbacks,\n SelectOption,\n SelectOptionGroup,\n SelectField,\n MultiSelectField,\n} from '../../types/schema'\n\n// =============================================================================\n// Type Guards\n// =============================================================================\n\n/**\n * SelectOptionGroupの型ガード\n */\nfunction isOptionGroup(item: SelectOption | SelectOptionGroup): item is SelectOptionGroup {\n return 'options' in item && Array.isArray(item.options)\n}\n\n// =============================================================================\n// Select Class\n// =============================================================================\n\n/**\n * セレクトコンポーネント\n */\nexport class Select {\n private config: SelectConfig\n private state: SelectState\n private callbacks: SelectCallbacks\n private container: HTMLElement\n private instanceId: string\n private selectElement: HTMLSelectElement | null = null\n\n constructor(\n container: HTMLElement,\n config: SelectConfig,\n callbacks: SelectCallbacks = {}\n ) {\n this.config = config\n this.container = container\n this.callbacks = callbacks\n this.instanceId = generateId('select')\n this.state = this.createInitialState()\n }\n\n // ===========================================================================\n // Public Methods\n // ===========================================================================\n\n /**\n * セレクトをレンダリング\n */\n render(): void {\n this.container.innerHTML = ''\n\n const size = this.config.size ?? 'default'\n this.container.className = `mokkun-select select-${size}`\n\n // data-state属性を設定\n if (this.state.disabled) {\n this.container.setAttribute('data-disabled', '')\n } else {\n this.container.removeAttribute('data-disabled')\n }\n\n if (this.state.error) {\n this.container.setAttribute('data-error', '')\n } else {\n this.container.removeAttribute('data-error')\n }\n\n // セレクト要素を作成\n const select = this.renderSelect()\n this.selectElement = select\n this.container.appendChild(select)\n }\n\n /**\n * 値を設定\n */\n setValue(value: string | number | null): void {\n if (this.state.disabled) {\n return\n }\n\n const stringValue = value === null ? '' : String(value)\n\n if (this.state.value === value) {\n return\n }\n\n this.state = {\n ...this.state,\n value,\n }\n\n if (this.selectElement) {\n this.selectElement.value = stringValue\n }\n\n this.callbacks.onChange?.(value, this.state)\n }\n\n /**\n * 無効化状態を設定\n */\n setDisabled(disabled: boolean): void {\n if (this.state.disabled === disabled) {\n return\n }\n\n this.state = {\n ...this.state,\n disabled,\n }\n\n this.render()\n }\n\n /**\n * エラー状態を設定\n */\n setError(error: boolean): void {\n if (this.state.error === error) {\n return\n }\n\n this.state = {\n ...this.state,\n error,\n }\n\n this.render()\n }\n\n /**\n * 現在の状態を取得\n */\n getState(): SelectState {\n return { ...this.state }\n }\n\n /**\n * 現在の値を取得\n */\n getValue(): string | number | null {\n return this.state.value\n }\n\n /**\n * 無効化されているかどうかを取得\n */\n isDisabled(): boolean {\n return this.state.disabled\n }\n\n /**\n * エラー状態かどうかを取得\n */\n hasError(): boolean {\n return this.state.error\n }\n\n // ===========================================================================\n // Private Methods\n // ===========================================================================\n\n /**\n * 初期状態を作成\n */\n private createInitialState(): SelectState {\n return {\n value: this.config.defaultValue ?? null,\n disabled: this.config.disabled ?? false,\n error: this.config.error ?? false,\n }\n }\n\n /**\n * セレクト要素をレンダリング\n */\n private renderSelect(): HTMLSelectElement {\n const classNames = [\n 'field-input',\n 'field-select',\n this.state.error ? 'error' : '',\n ].filter(Boolean).join(' ')\n\n const select = createElement('select', {\n className: classNames,\n attributes: {\n id: this.instanceId,\n 'aria-invalid': this.state.error ? 'true' : 'false',\n },\n })\n\n // name属性\n if (this.config.name) {\n select.setAttribute('name', this.config.name)\n }\n\n // 幅の設定\n if (this.config.width) {\n const width = typeof this.config.width === 'number'\n ? `${this.config.width}px`\n : this.config.width\n select.style.width = width\n }\n\n // 無効化\n if (this.state.disabled) {\n select.setAttribute('disabled', 'disabled')\n select.setAttribute('aria-disabled', 'true')\n }\n\n // 必須\n if (this.config.required) {\n select.setAttribute('required', 'required')\n select.setAttribute('aria-required', 'true')\n }\n\n // 空オプション(プレースホルダー)\n if (this.config.hasBlank !== false) {\n const blankOption = createElement('option', {\n textContent: this.config.placeholder ??\n this.config.blankLabel ??\n 'Select...',\n })\n blankOption.value = ''\n if (this.state.value === null || this.state.value === '') {\n blankOption.selected = true\n }\n select.appendChild(blankOption)\n }\n\n // オプションまたはオプショングループを追加\n this.appendOptions(select, this.config.options)\n\n // 変更イベント\n select.addEventListener('change', (e) => {\n const target = e.target as HTMLSelectElement\n const value = target.value === '' ? null : target.value\n this.setValue(value)\n })\n\n // キーボードナビゲーション\n select.addEventListener('keydown', (e) => {\n // Escape でフォーカスを外す\n if (e.key === 'Escape') {\n select.blur()\n }\n })\n\n return select\n }\n\n /**\n * オプションを追加\n */\n private appendOptions(\n select: HTMLSelectElement,\n items: Array<SelectOption | SelectOptionGroup>\n ): void {\n for (const item of items) {\n if (isOptionGroup(item)) {\n // オプショングループ\n const optgroup = this.createOptgroup(item)\n select.appendChild(optgroup)\n } else {\n // 単一オプション\n const option = this.createOption(item)\n select.appendChild(option)\n }\n }\n }\n\n /**\n * オプションを作成\n */\n private createOption(opt: SelectOption): HTMLOptionElement {\n const option = createElement('option', {\n textContent: opt.label,\n })\n\n option.value = String(opt.value)\n\n if (opt.disabled) {\n option.disabled = true\n }\n\n // 選択状態\n if (this.state.value !== null && String(opt.value) === String(this.state.value)) {\n option.selected = true\n }\n\n return option\n }\n\n /**\n * オプショングループを作成\n */\n private createOptgroup(group: SelectOptionGroup): HTMLOptGroupElement {\n const optgroup = document.createElement('optgroup')\n optgroup.label = group.label\n\n if (group.disabled) {\n optgroup.disabled = true\n }\n\n // グループ内のオプションを追加\n for (const opt of group.options) {\n const option = this.createOption(opt)\n optgroup.appendChild(option)\n }\n\n return optgroup\n }\n\n // ===========================================================================\n // Static Field Renderers\n // ===========================================================================\n\n /**\n * セレクトフィールドをHTMLとしてレンダリング(静的メソッド)\n * SSR/初期レンダリング用\n *\n * @param field - セレクトフィールド定義(select, multi_select)\n * @returns 生成されたHTML文字列\n */\n static renderField(field: SelectField | MultiSelectField): string {\n if (field.type === 'multi_select') {\n return Select.renderMultiSelectField(field)\n }\n return Select.renderSelectField(field)\n }\n\n /**\n * 単一セレクトフィールドをHTMLとしてレンダリング\n * @internal renderFieldから呼び出される内部メソッド\n */\n private static renderSelectField(field: SelectField): string {\n const attrs: string[] = [getCommonAttributes(field)]\n const sizeClass = field.size ? `select-${field.size}` : 'select-default'\n const options = getOptions(field.options)\n\n // グループ化されたオプションとそうでないオプションを分離\n const grouped = new Map<string, SelectOption[]>()\n const ungrouped: SelectOption[] = []\n\n for (const opt of options) {\n if (opt.group) {\n if (!grouped.has(opt.group)) {\n grouped.set(opt.group, [])\n }\n grouped.get(opt.group)!.push(opt)\n } else {\n ungrouped.push(opt)\n }\n }\n\n // オプションHTMLの生成\n const renderOption = (opt: SelectOption) => {\n const selected = field.default === opt.value ? 'selected' : ''\n const disabled = opt.disabled ? 'disabled' : ''\n return `<option value=\"${escapeHtml(String(opt.value))}\" ${selected} ${disabled}>${escapeHtml(opt.label)}</option>`\n }\n\n // 未グループ化のオプション\n const ungroupedHtml = ungrouped.map(renderOption).join('')\n\n // グループ化されたオプション(optgroup)\n const groupedHtml = Array.from(grouped.entries())\n .map(([label, opts]) => {\n const optionsHtml = opts.map(renderOption).join('')\n return `<optgroup label=\"${escapeHtml(label)}\">${optionsHtml}</optgroup>`\n })\n .join('')\n\n // プレースホルダーまたは空オプション\n const hasBlank = !field.required || field.clearable\n const blankOption = hasBlank\n ? `<option value=\"\">${escapeHtml(field.placeholder ?? 'Select...')}</option>`\n : ''\n\n const select = `\n <select class=\"field-select ${sizeClass}\" ${attrs.join(' ')}>\n ${blankOption}\n ${ungroupedHtml}\n ${groupedHtml}\n </select>\n `\n return createFieldWrapper(field, select)\n }\n\n /**\n * マルチセレクトフィールドをHTMLとしてレンダリング\n * @internal renderFieldから呼び出される内部メソッド\n */\n private static renderMultiSelectField(field: MultiSelectField): string {\n const attrs: string[] = [getCommonAttributes(field), 'multiple']\n const options = getOptions(field.options)\n const defaultValues = Array.isArray(field.default) ? field.default : []\n\n const optionHtml = options\n .map((opt) => {\n const selected = defaultValues.includes(opt.value) ? 'selected' : ''\n const disabled = opt.disabled ? 'disabled' : ''\n return `<option value=\"${escapeHtml(String(opt.value))}\" ${selected} ${disabled}>${escapeHtml(opt.label)}</option>`\n })\n .join('')\n\n const select = `\n <select class=\"form-select form-multiselect\" ${attrs.join(' ')}>\n ${optionHtml}\n </select>\n `\n return createFieldWrapper(field, select)\n }\n}\n\n// =============================================================================\n// Factory Function\n// =============================================================================\n\n/**\n * Selectを作成するファクトリ関数\n */\nexport function createSelect(\n container: HTMLElement,\n config: SelectConfig,\n callbacks: SelectCallbacks = {}\n): Select {\n const select = new Select(container, config, callbacks)\n select.render()\n return select\n}\n","/**\n * RadioButton Component\n * ラジオボタンコンポーネント\n *\n * \n * - `checked` / `defaultChecked` for state\n * - `data-state=\"checked|unchecked\"` for styling\n * - `error` state with error messages\n * - `role=\"radio\"` with `aria-checked` for accessibility\n */\n\nimport { createElement, generateId } from '../utils/dom'\nimport {\n escapeHtml,\n createFieldWrapper,\n getOptions,\n} from '../utils/field-helpers'\nimport type { RadioGroupField } from '../../types/schema'\n\n// =============================================================================\n// Types\n// =============================================================================\n\n/**\n * ラジオボタンの状態\n */\nexport interface RadioButtonState {\n /** 選択状態 */\n checked: boolean\n /** 無効化状態 */\n disabled: boolean\n}\n\n/**\n * ラジオボタンのコールバック\n */\nexport interface RadioButtonCallbacks {\n /** 状態変更時 */\n onChange?: (checked: boolean, state: RadioButtonState) => void\n /** 選択状態変更時 */\n onCheckedChange?: (checked: boolean) => void\n}\n\n/**\n * ラジオボタンの設定\n */\nexport interface RadioButtonConfig {\n /** 初期選択状態 */\n defaultChecked?: boolean\n /** 無効化 */\n disabled?: boolean\n /** 選択時ラベル */\n checkedLabel?: string\n /** 非選択時ラベル */\n uncheckedLabel?: string\n /** サイズ */\n size?: 'small' | 'medium' | 'large'\n /** name属性(グループ化用) */\n name?: string\n /** value属性 */\n value?: string\n /** ラベル位置 */\n labelPosition?: 'left' | 'right'\n}\n\n// =============================================================================\n// RadioButton Class\n// =============================================================================\n\n/**\n * ラジオボタンコンポーネント\n */\nexport class RadioButton {\n private config: RadioButtonConfig\n private state: RadioButtonState\n private callbacks: RadioButtonCallbacks\n private container: HTMLElement\n private instanceId: string\n\n constructor(\n container: HTMLElement,\n config: RadioButtonConfig = {},\n callbacks: RadioButtonCallbacks = {}\n ) {\n this.config = config\n this.container = container\n this.callbacks = callbacks\n this.instanceId = generateId('radio')\n this.state = this.createInitialState()\n }\n\n // ===========================================================================\n // Public Methods\n // ===========================================================================\n\n /**\n * ラジオボタンをレンダリング\n */\n render(): void {\n this.container.innerHTML = ''\n\n const size = this.config.size ?? 'medium'\n const labelPosition = this.config.labelPosition ?? 'right'\n this.container.className = `mokkun-radio radio-${size} radio-label-${labelPosition}`\n\n // data-state属性を設定\n const dataState = this.state.checked ? 'checked' : 'unchecked'\n this.container.setAttribute('data-state', dataState)\n\n if (this.state.disabled) {\n this.container.setAttribute('data-disabled', '')\n } else {\n this.container.removeAttribute('data-disabled')\n }\n\n const wrapper = createElement('div', { className: 'radio-wrapper' })\n\n // ラベル(左側に配置する場合)\n if (labelPosition === 'left') {\n const label = this.renderLabel()\n wrapper.appendChild(label)\n }\n\n // ラジオボタン\n const radio = this.renderRadio()\n wrapper.appendChild(radio)\n\n // ラベル(右側に配置する場合)\n if (labelPosition === 'right') {\n const label = this.renderLabel()\n wrapper.appendChild(label)\n }\n\n this.container.appendChild(wrapper)\n }\n\n /**\n * 選択状態を設定\n */\n setChecked(checked: boolean): void {\n if (this.state.disabled) {\n return\n }\n\n if (this.state.checked === checked) {\n return\n }\n\n this.state = {\n ...this.state,\n checked,\n }\n\n this.render()\n this.callbacks.onChange?.(checked, this.state)\n this.callbacks.onCheckedChange?.(checked)\n }\n\n /**\n * 無効化状態を設定\n */\n setDisabled(disabled: boolean): void {\n if (this.state.disabled === disabled) {\n return\n }\n\n this.state = {\n ...this.state,\n disabled,\n }\n\n this.render()\n }\n\n /**\n * 現在の状態を取得\n */\n getState(): RadioButtonState {\n return { ...this.state }\n }\n\n /**\n * 選択状態を取得\n */\n isChecked(): boolean {\n return this.state.checked\n }\n\n /**\n * 無効化されているかどうかを取得\n */\n isDisabled(): boolean {\n return this.state.disabled\n }\n\n /**\n * value属性を取得\n */\n getValue(): string | undefined {\n return this.config.value\n }\n\n /**\n * name属性を取得\n */\n getName(): string | undefined {\n return this.config.name\n }\n\n // ===========================================================================\n // Private Methods\n // ===========================================================================\n\n /**\n * 初期状態を作成\n */\n private createInitialState(): RadioButtonState {\n return {\n checked: this.config.defaultChecked ?? false,\n disabled: this.config.disabled ?? false,\n }\n }\n\n /**\n * ラジオボタンをレンダリング\n */\n private renderRadio(): HTMLElement {\n const radioContainer = createElement('div', {\n className: 'radio-input-container',\n })\n\n // ラジオボタン入力要素\n const input = createElement('input', {\n className: 'radio-input',\n attributes: {\n type: 'radio',\n id: this.instanceId,\n role: 'radio',\n 'aria-checked': String(this.state.checked),\n 'aria-label': this.state.checked\n ? (this.config.checkedLabel ?? '選択済み')\n : (this.config.uncheckedLabel ?? '未選択'),\n },\n })\n\n if (this.config.name) {\n input.setAttribute('name', this.config.name)\n }\n\n if (this.config.value) {\n input.setAttribute('value', this.config.value)\n }\n\n if (this.state.checked) {\n input.setAttribute('checked', 'checked')\n }\n\n if (this.state.disabled) {\n input.setAttribute('disabled', 'disabled')\n input.setAttribute('aria-disabled', 'true')\n }\n\n // 変更イベント\n input.addEventListener('change', (e) => {\n const target = e.target as HTMLInputElement\n this.setChecked(target.checked)\n })\n\n // キーボードイベント(Spaceキー対応)\n input.addEventListener('keydown', (e) => {\n if (e.key === ' ' || e.key === 'Enter') {\n e.preventDefault()\n if (!this.state.disabled) {\n this.setChecked(true)\n }\n }\n })\n\n radioContainer.appendChild(input)\n\n // 視覚的なラジオボタン\n const dataState = this.state.checked ? 'checked' : 'unchecked'\n const classNames = [\n 'radio-visual',\n dataState,\n this.state.disabled ? 'disabled' : '',\n ].filter(Boolean).join(' ')\n\n const visualRadio = createElement('label', {\n className: classNames,\n attributes: {\n for: this.instanceId,\n 'data-state': dataState,\n },\n })\n\n if (this.state.disabled) {\n visualRadio.setAttribute('data-disabled', '')\n }\n\n // ラジオボタンの枠\n const circle = createElement('span', { className: 'radio-circle' })\n\n // 選択マーク(内側の円)\n const dot = createElement('span', {\n className: 'radio-dot',\n attributes: {\n 'data-state': dataState,\n },\n })\n\n circle.appendChild(dot)\n visualRadio.appendChild(circle)\n\n radioContainer.appendChild(visualRadio)\n\n return radioContainer\n }\n\n /**\n * ラベルをレンダリング\n */\n private renderLabel(): HTMLElement {\n const checkedLabel = this.config.checkedLabel ?? ''\n const uncheckedLabel = this.config.uncheckedLabel ?? ''\n\n const dataState = this.state.checked ? 'checked' : 'unchecked'\n const classNames = [\n 'radio-label',\n dataState,\n this.state.disabled ? 'disabled' : '',\n ].filter(Boolean).join(' ')\n\n const labelText = this.state.checked ? checkedLabel : uncheckedLabel\n const label = createElement('label', {\n className: classNames,\n textContent: labelText,\n attributes: {\n 'for': this.instanceId,\n 'aria-live': 'polite',\n 'data-state': dataState,\n },\n })\n\n if (this.state.disabled) {\n label.setAttribute('data-disabled', '')\n }\n\n return label\n }\n\n // ===========================================================================\n // Static Field Renderer\n // ===========================================================================\n\n /**\n * ラジオグループフィールドをHTMLとしてレンダリング(静的メソッド)\n * SSR/初期レンダリング用\n *\n * @param field - ラジオグループフィールド定義\n * @returns 生成されたHTML文字列\n */\n static renderField(field: RadioGroupField): string {\n const options = getOptions(field.options)\n const direction = field.direction ?? 'vertical'\n\n const optionHtml = options\n .map((opt) => {\n const checked = field.default === opt.value ? 'checked' : ''\n const disabled = opt.disabled || field.disabled ? 'disabled' : ''\n const optionId = `${field.id}-${opt.value}`\n\n const descriptionHtml = opt.description\n ? `<span class=\"radio-option-description\">${escapeHtml(opt.description)}</span>`\n : ''\n\n return `\n <label class=\"radio-option\" for=\"${escapeHtml(optionId)}\">\n <input\n type=\"radio\"\n id=\"${escapeHtml(optionId)}\"\n name=\"${escapeHtml(field.id)}\"\n value=\"${escapeHtml(String(opt.value))}\"\n ${checked}\n ${disabled}\n ${field.required ? 'required' : ''}\n />\n <span class=\"radio-label-group\">\n <span class=\"radio-label\">${escapeHtml(opt.label)}</span>\n ${descriptionHtml}\n </span>\n </label>\n `\n })\n .join('')\n\n const content = `<div class=\"radio-group direction-${direction}\">${optionHtml}</div>`\n return createFieldWrapper(field, content)\n }\n}\n\n// =============================================================================\n// Factory Function\n// =============================================================================\n\n/**\n * RadioButtonを作成するファクトリ関数\n */\nexport function createRadioButton(\n container: HTMLElement,\n config: RadioButtonConfig = {},\n callbacks: RadioButtonCallbacks = {}\n): RadioButton {\n const radio = new RadioButton(container, config, callbacks)\n radio.render()\n return radio\n}\n","/**\n * Checkbox Component\n * チェックボックスコンポーネント\n *\n * \n * - `checked` / `defaultChecked` for state\n * - `indeterminate` state support (一部選択)\n * - `data-state=\"checked|unchecked|indeterminate\"` for styling\n * - `error` state with error messages\n * - `role=\"checkbox\"` with `aria-checked` for accessibility\n */\n\nimport { createElement, generateId } from '../utils/dom'\nimport {\n escapeHtml,\n createFieldWrapper,\n getOptions,\n} from '../utils/field-helpers'\nimport type { CheckboxField, CheckboxGroupField, InputField } from '../../types/schema'\n\n// =============================================================================\n// Types\n// =============================================================================\n\n/**\n * チェックボックスの状態\n */\nexport interface CheckboxState {\n /** チェック状態 */\n checked: boolean\n /** 中間状態(一部選択) */\n indeterminate: boolean\n /** 無効化状態 */\n disabled: boolean\n}\n\n/**\n * チェックボックスのコールバック\n */\nexport interface CheckboxCallbacks {\n /** 状態変更時 */\n onChange?: (checked: boolean, state: CheckboxState) => void\n /** チェック状態変更時 */\n onCheckedChange?: (checked: boolean) => void\n}\n\n/**\n * チェックボックスの設定\n */\nexport interface CheckboxConfig {\n /** 初期チェック状態 */\n defaultChecked?: boolean\n /** 初期中間状態 */\n defaultIndeterminate?: boolean\n /** 無効化 */\n disabled?: boolean\n /** チェック時ラベル */\n checkedLabel?: string\n /** 非チェック時ラベル */\n uncheckedLabel?: string\n /** サイズ */\n size?: 'small' | 'medium' | 'large'\n /** name属性(フォーム用) */\n name?: string\n /** ラベル位置 */\n labelPosition?: 'left' | 'right'\n}\n\n// =============================================================================\n// Checkbox Class\n// =============================================================================\n\n/**\n * チェックボックスコンポーネント\n */\nexport class Checkbox {\n private config: CheckboxConfig\n private state: CheckboxState\n private callbacks: CheckboxCallbacks\n private container: HTMLElement\n private instanceId: string\n\n constructor(\n container: HTMLElement,\n config: CheckboxConfig = {},\n callbacks: CheckboxCallbacks = {}\n ) {\n this.config = config\n this.container = container\n this.callbacks = callbacks\n this.instanceId = generateId('checkbox')\n this.state = this.createInitialState()\n }\n\n // ===========================================================================\n // Public Methods\n // ===========================================================================\n\n /**\n * チェックボックスをレンダリング\n */\n render(): void {\n this.container.innerHTML = ''\n\n const size = this.config.size ?? 'medium'\n const labelPosition = this.config.labelPosition ?? 'right'\n this.container.className = `mokkun-checkbox checkbox-${size} checkbox-label-${labelPosition}`\n\n // data-state属性を設定\n const dataState = this.state.indeterminate\n ? 'indeterminate'\n : this.state.checked\n ? 'checked'\n : 'unchecked'\n this.container.setAttribute('data-state', dataState)\n\n if (this.state.disabled) {\n this.container.setAttribute('data-disabled', '')\n } else {\n this.container.removeAttribute('data-disabled')\n }\n\n const wrapper = createElement('div', { className: 'checkbox-wrapper' })\n\n // ラベル(左側に配置する場合)\n if (labelPosition === 'left') {\n const label = this.renderLabel()\n wrapper.appendChild(label)\n }\n\n // チェックボックス\n const checkbox = this.renderCheckbox()\n wrapper.appendChild(checkbox)\n\n // ラベル(右側に配置する場合)\n if (labelPosition === 'right') {\n const label = this.renderLabel()\n wrapper.appendChild(label)\n }\n\n this.container.appendChild(wrapper)\n }\n\n /**\n * チェック状態を設定\n */\n setChecked(checked: boolean): void {\n if (this.state.disabled) {\n return\n }\n\n if (this.state.checked === checked && !this.state.indeterminate) {\n return\n }\n\n this.state = {\n ...this.state,\n checked,\n indeterminate: false, // チェック状態を設定すると中間状態は解除\n }\n\n this.render()\n this.callbacks.onChange?.(checked, this.state)\n this.callbacks.onCheckedChange?.(checked)\n }\n\n /**\n * 中間状態を設定\n */\n setIndeterminate(indeterminate: boolean): void {\n if (this.state.disabled) {\n return\n }\n\n if (this.state.indeterminate === indeterminate) {\n return\n }\n\n this.state = {\n ...this.state,\n indeterminate,\n }\n\n this.render()\n }\n\n /**\n * 状態をトグル\n */\n toggle(): void {\n // 中間状態の場合はチェック状態にする\n if (this.state.indeterminate) {\n this.setChecked(true)\n } else {\n this.setChecked(!this.state.checked)\n }\n }\n\n /**\n * 無効化状態を設定\n */\n setDisabled(disabled: boolean): void {\n if (this.state.disabled === disabled) {\n return\n }\n\n this.state = {\n ...this.state,\n disabled,\n }\n\n this.render()\n }\n\n /**\n * 現在の状態を取得\n */\n getState(): CheckboxState {\n return { ...this.state }\n }\n\n /**\n * チェック状態を取得\n */\n isChecked(): boolean {\n return this.state.checked\n }\n\n /**\n * 中間状態かどうかを取得\n */\n isIndeterminate(): boolean {\n return this.state.indeterminate\n }\n\n /**\n * 無効化されているかどうかを取得\n */\n isDisabled(): boolean {\n return this.state.disabled\n }\n\n // ===========================================================================\n // Private Methods\n // ===========================================================================\n\n /**\n * 初期状態を作成\n */\n private createInitialState(): CheckboxState {\n return {\n checked: this.config.defaultChecked ?? false,\n indeterminate: this.config.defaultIndeterminate ?? false,\n disabled: this.config.disabled ?? false,\n }\n }\n\n /**\n * チェックボックスをレンダリング\n */\n private renderCheckbox(): HTMLElement {\n const checkboxContainer = createElement('div', {\n className: 'checkbox-input-container',\n })\n\n // チェックボックス入力要素\n const input = createElement('input', {\n className: 'checkbox-input',\n attributes: {\n type: 'checkbox',\n id: this.instanceId,\n role: 'checkbox',\n 'aria-checked': this.state.indeterminate\n ? 'mixed'\n : String(this.state.checked),\n 'aria-label': this.state.checked\n ? (this.config.checkedLabel ?? 'チェック済み')\n : (this.config.uncheckedLabel ?? '未チェック'),\n },\n })\n\n if (this.config.name) {\n input.setAttribute('name', this.config.name)\n }\n\n if (this.state.checked) {\n input.setAttribute('checked', 'checked')\n }\n\n if (this.state.indeterminate) {\n (input as HTMLInputElement).indeterminate = true\n }\n\n if (this.state.disabled) {\n input.setAttribute('disabled', 'disabled')\n input.setAttribute('aria-disabled', 'true')\n }\n\n // 変更イベント\n input.addEventListener('change', (e) => {\n const target = e.target as HTMLInputElement\n this.setChecked(target.checked)\n })\n\n // キーボードイベント(Spaceキー対応)\n input.addEventListener('keydown', (e) => {\n if (e.key === ' ' || e.key === 'Enter') {\n e.preventDefault()\n if (!this.state.disabled) {\n this.toggle()\n }\n }\n })\n\n checkboxContainer.appendChild(input)\n\n // 視覚的なチェックボックス\n const dataState = this.state.indeterminate\n ? 'indeterminate'\n : this.state.checked\n ? 'checked'\n : 'unchecked'\n const classNames = [\n 'checkbox-visual',\n dataState,\n this.state.disabled ? 'disabled' : '',\n ].filter(Boolean).join(' ')\n\n const visualCheckbox = createElement('label', {\n className: classNames,\n attributes: {\n for: this.instanceId,\n 'data-state': dataState,\n },\n })\n\n if (this.state.disabled) {\n visualCheckbox.setAttribute('data-disabled', '')\n }\n\n // チェックボックスの枠\n const box = createElement('span', { className: 'checkbox-box' })\n\n // チェックマーク/インデタミネートマーク\n const icon = createElement('span', {\n className: 'checkbox-icon',\n attributes: {\n 'data-state': dataState,\n },\n })\n\n // SVGアイコン(チェックマーク or インデタミネートマーク)\n if (this.state.indeterminate) {\n icon.innerHTML = `\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M3 8H13\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\"/>\n </svg>\n `\n } else if (this.state.checked) {\n icon.innerHTML = `\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M3 8L6.5 11.5L13 4.5\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\n </svg>\n `\n }\n\n box.appendChild(icon)\n visualCheckbox.appendChild(box)\n\n checkboxContainer.appendChild(visualCheckbox)\n\n return checkboxContainer\n }\n\n /**\n * ラベルをレンダリング\n */\n private renderLabel(): HTMLElement {\n const checkedLabel = this.config.checkedLabel ?? ''\n const uncheckedLabel = this.config.uncheckedLabel ?? ''\n\n const dataState = this.state.indeterminate\n ? 'indeterminate'\n : this.state.checked\n ? 'checked'\n : 'unchecked'\n const classNames = [\n 'checkbox-label',\n dataState,\n this.state.disabled ? 'disabled' : '',\n ].filter(Boolean).join(' ')\n\n const labelText = this.state.checked ? checkedLabel : uncheckedLabel\n const label = createElement('label', {\n className: classNames,\n textContent: labelText,\n attributes: {\n 'for': this.instanceId,\n 'aria-live': 'polite',\n 'data-state': dataState,\n },\n })\n\n if (this.state.disabled) {\n label.setAttribute('data-disabled', '')\n }\n\n return label\n }\n\n // ===========================================================================\n // Static Field Renderer\n // ===========================================================================\n\n /**\n * チェックボックスグループフィールドをHTMLとしてレンダリング(静的メソッド)\n * SSR/初期レンダリング用\n *\n * @param field - チェックボックスグループフィールド定義\n * @returns 生成されたHTML文字列\n */\n static renderField(field: InputField): string {\n if (field.type === 'checkbox') {\n return Checkbox.renderSingleCheckbox(field as CheckboxField)\n }\n return Checkbox.renderCheckboxGroup(field as CheckboxGroupField)\n }\n\n /**\n * 単一チェックボックスをレンダリング\n */\n private static renderSingleCheckbox(field: CheckboxField): string {\n const labelPosition = field.label_position ?? 'right'\n const size = field.size ?? 'medium'\n const disabled = field.disabled ? 'disabled' : ''\n\n const checkboxInput = `\n <input\n type=\"checkbox\"\n id=\"${escapeHtml(field.id)}\"\n name=\"${escapeHtml(field.name ?? field.id)}\"\n class=\"checkbox-input checkbox-${size}\"\n ${field.required ? 'required' : ''}\n ${disabled}\n />\n `\n\n const labelText = field.label ? `<span class=\"checkbox-label-text\">${escapeHtml(field.label)}</span>` : ''\n\n const content = labelPosition === 'left'\n ? `<label class=\"checkbox-single label-left\">${labelText}${checkboxInput}</label>`\n : `<label class=\"checkbox-single label-right\">${checkboxInput}${labelText}</label>`\n\n return createFieldWrapper({ ...field, label: '' }, content)\n }\n\n /**\n * チェックボックスグループをレンダリング\n */\n private static renderCheckboxGroup(field: CheckboxGroupField): string {\n const options = getOptions(field.options)\n const direction = field.direction ?? 'vertical'\n const defaultValues = Array.isArray(field.default) ? field.default : []\n\n const optionHtml = options\n .map((opt) => {\n const checked = defaultValues.includes(opt.value) ? 'checked' : ''\n const disabled = opt.disabled || field.disabled ? 'disabled' : ''\n const optionId = `${field.id}-${opt.value}`\n\n return `\n <label class=\"checkbox-option\" for=\"${escapeHtml(optionId)}\">\n <input\n type=\"checkbox\"\n id=\"${escapeHtml(optionId)}\"\n name=\"${escapeHtml(field.id)}\"\n value=\"${escapeHtml(String(opt.value))}\"\n ${checked}\n ${disabled}\n />\n <span class=\"checkbox-label\">${escapeHtml(opt.label)}</span>\n </label>\n `\n })\n .join('')\n\n const content = `<div class=\"checkbox-group direction-${direction}\">${optionHtml}</div>`\n return createFieldWrapper(field, content)\n }\n}\n\n// =============================================================================\n// Factory Function\n// =============================================================================\n\n/**\n * Checkboxを作成するファクトリ関数\n */\nexport function createCheckbox(\n container: HTMLElement,\n config: CheckboxConfig = {},\n callbacks: CheckboxCallbacks = {}\n): Checkbox {\n const checkbox = new Checkbox(container, config, callbacks)\n checkbox.render()\n return checkbox\n}\n","/**\n * Combobox Component\n * コンボボックスコンポーネント\n *\n * Features:\n * - Single and multi-selection modes\n * - Search/filter functionality\n * - Async option loading with debounce\n * - Grouped options support\n * - Custom option rendering\n * - Full keyboard navigation\n * - ARIA accessibility\n *\n * API follows standard conventions from Headless UI and Radix UI:\n * - `role=\"combobox\"` with `aria-haspopup=\"listbox\"`\n * - `aria-expanded` for dropdown state\n * - `aria-activedescendant` for keyboard navigation\n * - `data-state=\"open|closed\"` for styling\n */\n\nimport { createElement, generateId, clearElement } from '../utils/dom'\nimport {\n escapeHtml,\n createFieldWrapper,\n getOptions,\n} from '../utils/field-helpers'\nimport type { ComboboxField } from '../../types/schema'\n\n// =============================================================================\n// Types\n// =============================================================================\n\n/**\n * コンボボックスの選択肢\n */\nexport interface ComboboxOption {\n /** 値 */\n value: string | number\n /** ラベル */\n label: string\n /** 無効化 */\n disabled?: boolean\n /** グループ名 */\n group?: string\n /** アイコンHTML */\n icon?: string\n /** 説明 */\n description?: string\n /** カスタムデータ */\n data?: Record<string, unknown>\n}\n\n/**\n * コンボボックスの状態\n */\nexport interface ComboboxState {\n /** 選択された値 */\n selectedValues: (string | number)[]\n /** 入力テキスト */\n inputValue: string\n /** ドロップダウン開閉状態 */\n isOpen: boolean\n /** ハイライト中のオプションインデックス */\n highlightedIndex: number\n /** フィルタリング/ロード済みオプション */\n filteredOptions: ComboboxOption[]\n /** グループ化されたオプション */\n groupedOptions: Map<string, ComboboxOption[]>\n /** ローディング状態 */\n isLoading: boolean\n /** エラーメッセージ */\n error: string | null\n}\n\n/**\n * コンボボックスのコールバック\n */\nexport interface ComboboxCallbacks {\n /** 選択変更時 */\n onChange?: (values: (string | number)[], state: ComboboxState) => void\n /** 入力変更時 */\n onInputChange?: (value: string, state: ComboboxState) => void\n /** ドロップダウン開閉時 */\n onOpen?: (state: ComboboxState) => void\n /** ドロップダウン閉じる時 */\n onClose?: (state: ComboboxState) => void\n /** オプションハイライト時 */\n onHighlight?: (option: ComboboxOption | null, state: ComboboxState) => void\n /** 非同期ロードエラー時 */\n onError?: (error: Error, state: ComboboxState) => void\n}\n\n/**\n * コンボボックスの設定\n */\nexport interface ComboboxConfig {\n /** コンポーネントID */\n id: string\n /** プレースホルダー */\n placeholder?: string\n /** 選択モード */\n mode: 'single' | 'multi'\n /** 静的オプション */\n options?: ComboboxOption[]\n /** 非同期ローダー関数 */\n loadOptions?: (query: string) => Promise<ComboboxOption[]>\n /** デバウンス遅延(ms) */\n debounceMs?: number\n /** クリア可能 */\n clearable?: boolean\n /** 無効化 */\n disabled?: boolean\n /** 必須フィールド */\n required?: boolean\n /** 非同期ロード最小検索文字数 */\n minSearchLength?: number\n /** 最大選択数(multiモード) */\n maxSelections?: number\n /** カスタムオプションレンダラー */\n renderOption?: (option: ComboboxOption) => string\n /** カスタム選択値レンダラー */\n renderSelected?: (option: ComboboxOption) => string\n /** オプションなしメッセージ */\n noOptionsMessage?: string\n /** ローディングメッセージ */\n loadingMessage?: string\n /** name属性(フォーム用) */\n name?: string\n}\n\n// =============================================================================\n// Combobox Class\n// =============================================================================\n\n/**\n * コンボボックスコンポーネント\n */\nexport class Combobox {\n private config: ComboboxConfig\n private state: ComboboxState\n private callbacks: ComboboxCallbacks\n private container: HTMLElement\n private instanceId: string\n private debounceTimer: ReturnType<typeof setTimeout> | null = null\n private inputRef: HTMLInputElement | null = null\n private listboxRef: HTMLElement | null = null\n private documentClickHandler: ((e: MouseEvent) => void) | null = null\n private abortController: AbortController | null = null\n\n constructor(\n container: HTMLElement,\n config: ComboboxConfig,\n callbacks: ComboboxCallbacks = {},\n initialValues: (string | number)[] = []\n ) {\n this.config = config\n this.container = container\n this.callbacks = callbacks\n this.instanceId = generateId('combobox')\n this.state = this.createInitialState(initialValues)\n }\n\n // ===========================================================================\n // Public Methods\n // ===========================================================================\n\n /**\n * コンボボックスをレンダリング\n */\n render(): void {\n clearElement(this.container)\n this.container.className = `mokkun-combobox combobox-${this.config.mode}`\n this.container.setAttribute('data-state', this.state.isOpen ? 'open' : 'closed')\n\n if (this.config.disabled) {\n this.container.setAttribute('data-disabled', '')\n } else {\n this.container.removeAttribute('data-disabled')\n }\n\n // Build wrapper\n const wrapper = createElement('div', { className: 'combobox-wrapper' })\n\n // Input area\n wrapper.appendChild(this.renderInputArea())\n\n // Dropdown (when open)\n if (this.state.isOpen) {\n wrapper.appendChild(this.renderDropdown())\n }\n\n this.container.appendChild(wrapper)\n\n // Setup event listeners\n this.setupEventListeners()\n }\n\n /**\n * 値を取得\n */\n getValue(): (string | number)[] {\n return [...this.state.selectedValues]\n }\n\n /**\n * 値を設定\n */\n setValue(values: (string | number)[]): void {\n this.setState({ selectedValues: values })\n }\n\n /**\n * 選択されたオプションを取得\n */\n getSelectedOptions(): ComboboxOption[] {\n const allOptions = this.config.options ?? []\n return this.state.selectedValues\n .map((value) => allOptions.find((opt) => opt.value === value))\n .filter((opt): opt is ComboboxOption => opt !== undefined)\n }\n\n /**\n * ドロップダウンを開く\n */\n open(): void {\n if (this.config.disabled || this.state.isOpen) return\n this.setState({ isOpen: true, highlightedIndex: -1 })\n this.callbacks.onOpen?.(this.state)\n }\n\n /**\n * ドロップダウンを閉じる\n */\n close(): void {\n if (!this.state.isOpen) return\n this.setState({ isOpen: false, highlightedIndex: -1 })\n this.callbacks.onClose?.(this.state)\n }\n\n /**\n * ドロップダウンの開閉状態をトグル\n */\n toggle(): void {\n if (this.state.isOpen) {\n this.close()\n } else {\n this.open()\n }\n }\n\n /**\n * ドロップダウンが開いているか\n */\n isOpenState(): boolean {\n return this.state.isOpen\n }\n\n /**\n * オプションを設定\n */\n setOptions(options: ComboboxOption[]): void {\n this.config.options = options\n this.updateFilteredOptions()\n }\n\n /**\n * オプションを追加\n */\n addOption(option: ComboboxOption): void {\n if (!this.config.options) {\n this.config.options = []\n }\n this.config.options.push(option)\n this.updateFilteredOptions()\n }\n\n /**\n * オプションを削除\n */\n removeOption(value: string | number): void {\n if (!this.config.options) return\n this.config.options = this.config.options.filter((opt) => opt.value !== value)\n this.updateFilteredOptions()\n }\n\n /**\n * 状態を取得\n */\n getState(): ComboboxState {\n return { ...this.state }\n }\n\n /**\n * クリーンアップ\n */\n destroy(): void {\n if (this.debounceTimer) {\n clearTimeout(this.debounceTimer)\n }\n if (this.abortController) {\n this.abortController.abort()\n }\n if (this.documentClickHandler) {\n document.removeEventListener('click', this.documentClickHandler)\n }\n clearElement(this.container)\n this.inputRef = null\n this.listboxRef = null\n }\n\n // ===========================================================================\n // Private Methods - State Management\n // ===========================================================================\n\n private createInitialState(initialValues: (string | number)[]): ComboboxState {\n const options = this.config.options ?? []\n const filteredOptions = this.filterOptions('', options)\n return {\n selectedValues: initialValues,\n inputValue: '',\n isOpen: false,\n highlightedIndex: -1,\n filteredOptions,\n groupedOptions: this.groupOptions(filteredOptions),\n isLoading: false,\n error: null,\n }\n }\n\n private setState(partial: Partial<ComboboxState>): void {\n this.state = { ...this.state, ...partial }\n this.render()\n }\n\n private updateFilteredOptions(): void {\n const options = this.config.options ?? []\n const filteredOptions = this.filterOptions(this.state.inputValue, options)\n this.setState({\n filteredOptions,\n groupedOptions: this.groupOptions(filteredOptions),\n })\n }\n\n // ===========================================================================\n // Private Methods - Filtering and Grouping\n // ===========================================================================\n\n private filterOptions(query: string, options: ComboboxOption[]): ComboboxOption[] {\n if (!query) return options\n\n const normalized = query.toLowerCase().trim()\n return options.filter((option) => {\n // Don't filter out disabled options from display, just prevent interaction\n const labelMatch = option.label.toLowerCase().includes(normalized)\n const descMatch = option.description?.toLowerCase().includes(normalized) ?? false\n const groupMatch = option.group?.toLowerCase().includes(normalized) ?? false\n return labelMatch || descMatch || groupMatch\n })\n }\n\n private groupOptions(options: ComboboxOption[]): Map<string, ComboboxOption[]> {\n const grouped = new Map<string, ComboboxOption[]>()\n const ungrouped: ComboboxOption[] = []\n\n for (const option of options) {\n if (option.group) {\n if (!grouped.has(option.group)) {\n grouped.set(option.group, [])\n }\n grouped.get(option.group)!.push(option)\n } else {\n ungrouped.push(option)\n }\n }\n\n if (ungrouped.length > 0) {\n grouped.set('', ungrouped)\n }\n\n return grouped\n }\n\n // ===========================================================================\n // Private Methods - Async Loading\n // ===========================================================================\n\n private async loadOptionsAsync(query: string): Promise<void> {\n if (!this.config.loadOptions) return\n\n // Clear previous timer\n if (this.debounceTimer) {\n clearTimeout(this.debounceTimer)\n }\n\n // Check minimum search length\n const minLength = this.config.minSearchLength ?? 0\n if (query.length < minLength) {\n this.setState({\n filteredOptions: [],\n groupedOptions: new Map(),\n isLoading: false,\n error: null,\n })\n return\n }\n\n // Cancel previous request\n if (this.abortController) {\n this.abortController.abort()\n }\n this.abortController = new AbortController()\n\n // Set loading state\n this.setState({ isLoading: true, error: null })\n\n // Debounce\n this.debounceTimer = setTimeout(async () => {\n try {\n const options = await this.config.loadOptions!(query)\n const filteredOptions = this.filterOptions(query, options)\n this.setState({\n filteredOptions,\n groupedOptions: this.groupOptions(filteredOptions),\n isLoading: false,\n error: null,\n })\n } catch (error) {\n // Check if error is abort\n if ((error as Error).name === 'AbortError') return\n\n this.setState({\n isLoading: false,\n error: (error as Error).message,\n })\n this.callbacks.onError?.(error as Error, this.state)\n }\n }, this.config.debounceMs ?? 300)\n }\n\n // ===========================================================================\n // Private Methods - Rendering\n // ===========================================================================\n\n private renderInputArea(): HTMLElement {\n const control = createElement('div', {\n className: `combobox-control ${this.config.disabled ? 'disabled' : ''}`,\n })\n\n const valueContainer = createElement('div', { className: 'combobox-value-container' })\n\n if (this.config.mode === 'multi') {\n // Multi mode: tags + input\n const tagsContainer = this.renderTags()\n if (tagsContainer) {\n valueContainer.appendChild(tagsContainer)\n }\n } else {\n // Single mode: selected value or empty\n if (this.state.selectedValues.length > 0) {\n const selectedOption = this.getSelectedOptions()[0]\n if (selectedOption) {\n const singleValue = createElement('span', { className: 'combobox-single-value' })\n if (this.config.renderSelected) {\n singleValue.innerHTML = this.config.renderSelected(selectedOption)\n } else {\n singleValue.textContent = selectedOption.label\n }\n valueContainer.appendChild(singleValue)\n }\n }\n }\n\n // Input element\n const input = this.createInputElement()\n this.inputRef = input as HTMLInputElement\n valueContainer.appendChild(input)\n\n control.appendChild(valueContainer)\n\n // Indicators (clear + dropdown)\n const indicators = this.renderIndicators()\n control.appendChild(indicators)\n\n return control\n }\n\n private createInputElement(): HTMLElement {\n const attributes: Record<string, string> = {\n type: 'text',\n role: 'combobox',\n 'aria-haspopup': 'listbox',\n 'aria-expanded': String(this.state.isOpen),\n 'aria-controls': `${this.instanceId}-listbox`,\n 'aria-autocomplete': 'list',\n id: this.config.id,\n name: this.config.name ?? this.config.id,\n placeholder: this.config.placeholder ?? '',\n }\n\n if (this.config.disabled) {\n attributes.disabled = 'true'\n }\n if (this.config.required) {\n attributes.required = 'true'\n }\n\n const input = createElement('input', {\n className: 'combobox-input',\n attributes,\n }) as HTMLInputElement\n\n if (this.state.highlightedIndex >= 0 && this.state.filteredOptions[this.state.highlightedIndex]) {\n input.setAttribute(\n 'aria-activedescendant',\n `${this.instanceId}-option-${this.state.highlightedIndex}`\n )\n }\n\n return input\n }\n\n private renderTags(): HTMLElement | null {\n if (this.state.selectedValues.length === 0) return null\n\n const tagsContainer = createElement('div', { className: 'combobox-tags' })\n const selectedOptions = this.getSelectedOptions()\n\n for (const option of selectedOptions) {\n const tag = createElement('span', { className: 'combobox-tag' })\n\n const label = createElement('span', { className: 'combobox-tag-label' })\n if (this.config.renderSelected) {\n label.innerHTML = this.config.renderSelected(option)\n } else {\n label.textContent = option.label\n }\n tag.appendChild(label)\n\n const removeBtn = createElement('button', {\n className: 'combobox-tag-remove',\n attributes: {\n type: 'button',\n 'aria-label': `Remove ${option.label}`,\n 'data-value': String(option.value),\n },\n })\n removeBtn.textContent = '×'\n tag.appendChild(removeBtn)\n\n tagsContainer.appendChild(tag)\n }\n\n return tagsContainer\n }\n\n private renderIndicators(): HTMLElement {\n const indicators = createElement('div', { className: 'combobox-indicators' })\n\n // Clear button\n if (this.config.clearable && this.state.selectedValues.length > 0) {\n const clearBtn = createElement('button', {\n className: 'combobox-clear',\n attributes: {\n type: 'button',\n 'aria-label': 'Clear selection',\n },\n })\n clearBtn.textContent = '×'\n indicators.appendChild(clearBtn)\n\n const separator = createElement('span', { className: 'combobox-separator' })\n indicators.appendChild(separator)\n }\n\n // Dropdown indicator\n const dropdownBtn = createElement('button', {\n className: 'combobox-dropdown-indicator',\n attributes: {\n type: 'button',\n 'aria-label': this.state.isOpen ? 'Close options' : 'Open options',\n },\n })\n dropdownBtn.textContent = '▼'\n indicators.appendChild(dropdownBtn)\n\n return indicators\n }\n\n private renderDropdown(): HTMLElement {\n const dropdown = createElement('div', {\n className: 'combobox-dropdown',\n attributes: {\n role: 'listbox',\n id: `${this.instanceId}-listbox`,\n 'aria-label': 'Options',\n },\n })\n this.listboxRef = dropdown\n\n // Loading state\n if (this.state.isLoading) {\n const loading = createElement('div', { className: 'combobox-loading' })\n loading.textContent = this.config.loadingMessage ?? 'Loading...'\n dropdown.appendChild(loading)\n return dropdown\n }\n\n // Error state\n if (this.state.error) {\n const error = createElement('div', { className: 'combobox-error' })\n error.textContent = this.state.error\n dropdown.appendChild(error)\n return dropdown\n }\n\n // Empty state\n if (this.state.filteredOptions.length === 0) {\n const empty = createElement('div', { className: 'combobox-no-options' })\n empty.textContent = this.config.noOptionsMessage ?? 'No options found'\n dropdown.appendChild(empty)\n return dropdown\n }\n\n // Render grouped options\n let globalIndex = 0\n for (const [groupName, options] of this.state.groupedOptions.entries()) {\n const group = createElement('div', { className: 'combobox-option-group' })\n\n if (groupName) {\n const header = createElement('div', { className: 'combobox-group-header' })\n header.textContent = groupName\n group.appendChild(header)\n }\n\n for (const option of options) {\n const optionEl = this.renderOption(option, globalIndex)\n group.appendChild(optionEl)\n globalIndex++\n }\n\n dropdown.appendChild(group)\n }\n\n return dropdown\n }\n\n private renderOption(option: ComboboxOption, index: number): HTMLElement {\n const isSelected = this.state.selectedValues.includes(option.value)\n const isHighlighted = this.state.highlightedIndex === index\n\n const el = createElement('div', {\n className: `combobox-option ${isSelected ? 'selected' : ''} ${\n isHighlighted ? 'highlighted' : ''\n } ${option.disabled ? 'disabled' : ''}`,\n attributes: {\n role: 'option',\n 'aria-selected': String(isSelected),\n 'data-value': String(option.value),\n 'data-index': String(index),\n id: `${this.instanceId}-option-${index}`,\n },\n })\n\n if (this.config.renderOption) {\n el.innerHTML = this.config.renderOption(option)\n } else {\n if (option.icon) {\n const icon = createElement('span', { className: 'combobox-option-icon' })\n icon.innerHTML = option.icon\n el.appendChild(icon)\n }\n\n const label = createElement('span', { className: 'combobox-option-label' })\n label.textContent = option.label\n el.appendChild(label)\n\n if (option.description) {\n const desc = createElement('span', { className: 'combobox-option-description' })\n desc.textContent = option.description\n el.appendChild(desc)\n }\n }\n\n return el\n }\n\n // ===========================================================================\n // Private Methods - Event Handling\n // ===========================================================================\n\n private setupEventListeners(): void {\n if (!this.inputRef) return\n\n // Input events\n this.inputRef.addEventListener('focus', () => this.handleInputFocus())\n this.inputRef.addEventListener('input', (e) => this.handleInput(e))\n this.inputRef.addEventListener('keydown', (e) => this.handleKeyDown(e))\n\n // Clear button\n const clearBtn = this.container.querySelector('.combobox-clear')\n if (clearBtn) {\n clearBtn.addEventListener('click', () => this.handleClear())\n }\n\n // Dropdown indicator\n const dropdownBtn = this.container.querySelector('.combobox-dropdown-indicator')\n if (dropdownBtn) {\n dropdownBtn.addEventListener('click', () => this.toggle())\n }\n\n // Tag remove buttons\n const removeBtns = this.container.querySelectorAll('.combobox-tag-remove')\n removeBtns.forEach((btn) => {\n btn.addEventListener('click', (e) => {\n const value = (e.target as HTMLElement).closest('[data-value]')?.getAttribute('data-value')\n if (value !== null && value !== undefined) {\n this.deselectOption(value)\n }\n })\n })\n\n // Option clicks\n if (this.listboxRef) {\n this.listboxRef.addEventListener('click', (e) => this.handleOptionClick(e))\n this.listboxRef.addEventListener('mouseover', (e) => this.handleOptionHover(e))\n }\n\n // Document click for closing dropdown\n this.documentClickHandler = (e: MouseEvent) => {\n if (!this.container.contains(e.target as Node)) {\n this.close()\n }\n }\n document.addEventListener('click', this.documentClickHandler)\n }\n\n private handleInputFocus(): void {\n if (!this.state.isOpen) {\n this.open()\n }\n }\n\n private handleInput(e: Event): void {\n const input = e.target as HTMLInputElement\n const value = input.value\n\n this.state.inputValue = value\n this.callbacks.onInputChange?.(value, this.state)\n\n if (this.config.loadOptions) {\n this.loadOptionsAsync(value)\n } else {\n this.updateFilteredOptions()\n }\n\n if (!this.state.isOpen) {\n this.open()\n }\n }\n\n private handleKeyDown(e: KeyboardEvent): void {\n switch (e.key) {\n case 'ArrowDown':\n e.preventDefault()\n if (!this.state.isOpen) {\n this.open()\n } else {\n this.highlightNext()\n }\n break\n case 'ArrowUp':\n e.preventDefault()\n if (this.state.isOpen) {\n this.highlightPrevious()\n }\n break\n case 'Enter':\n e.preventDefault()\n if (this.state.isOpen && this.state.highlightedIndex >= 0) {\n this.selectHighlighted()\n }\n break\n case 'Escape':\n e.preventDefault()\n this.close()\n break\n case 'Tab':\n this.close()\n break\n case 'Backspace':\n if (this.config.mode === 'multi' && !this.state.inputValue) {\n this.removeLastSelected()\n }\n break\n }\n }\n\n private handleClear(): void {\n this.clearSelection()\n }\n\n private handleOptionClick(e: MouseEvent): void {\n const target = e.target as HTMLElement\n const optionEl = target.closest('.combobox-option') as HTMLElement\n if (!optionEl) return\n\n const value = optionEl.getAttribute('data-value')\n if (value === null) return\n\n const option = this.state.filteredOptions.find((opt) => String(opt.value) === value)\n if (!option || option.disabled) return\n\n this.selectOption(option.value)\n }\n\n private handleOptionHover(e: MouseEvent): void {\n const target = e.target as HTMLElement\n const optionEl = target.closest('.combobox-option') as HTMLElement\n if (!optionEl) return\n\n const index = parseInt(optionEl.getAttribute('data-index') ?? '-1')\n if (index >= 0) {\n this.highlightOption(index)\n }\n }\n\n // ===========================================================================\n // Private Methods - Selection\n // ===========================================================================\n\n private selectOption(value: string | number): void {\n if (this.config.mode === 'single') {\n // Single: replace selection\n this.setState({\n selectedValues: [value],\n inputValue: '',\n isOpen: false,\n })\n } else {\n // Multi: add to selection\n if (this.state.selectedValues.includes(value)) {\n // Already selected, deselect\n this.deselectOption(value)\n return\n }\n\n const maxSelections = this.config.maxSelections\n if (maxSelections && this.state.selectedValues.length >= maxSelections) {\n return\n }\n\n this.setState({\n selectedValues: [...this.state.selectedValues, value],\n inputValue: '',\n })\n }\n\n this.callbacks.onChange?.(this.state.selectedValues, this.state)\n }\n\n private deselectOption(value: string | number): void {\n this.setState({\n selectedValues: this.state.selectedValues.filter((v) => String(v) !== String(value)),\n })\n this.callbacks.onChange?.(this.state.selectedValues, this.state)\n }\n\n private clearSelection(): void {\n this.setState({ selectedValues: [], inputValue: '' })\n this.callbacks.onChange?.(this.state.selectedValues, this.state)\n }\n\n private selectHighlighted(): void {\n if (this.state.highlightedIndex < 0) return\n const option = this.state.filteredOptions[this.state.highlightedIndex]\n if (!option || option.disabled) return\n this.selectOption(option.value)\n }\n\n private removeLastSelected(): void {\n if (this.state.selectedValues.length === 0) return\n const lastValue = this.state.selectedValues[this.state.selectedValues.length - 1]\n this.deselectOption(lastValue)\n }\n\n // ===========================================================================\n // Private Methods - Highlighting\n // ===========================================================================\n\n private highlightNext(): void {\n let nextIndex = this.state.highlightedIndex + 1\n while (nextIndex < this.state.filteredOptions.length) {\n if (!this.state.filteredOptions[nextIndex].disabled) {\n this.highlightOption(nextIndex)\n return\n }\n nextIndex++\n }\n }\n\n private highlightPrevious(): void {\n let prevIndex = this.state.highlightedIndex - 1\n while (prevIndex >= 0) {\n if (!this.state.filteredOptions[prevIndex].disabled) {\n this.highlightOption(prevIndex)\n return\n }\n prevIndex--\n }\n }\n\n private highlightOption(index: number): void {\n if (index < 0 || index >= this.state.filteredOptions.length) return\n\n const prevIndex = this.state.highlightedIndex\n this.state.highlightedIndex = index\n\n // Update highlight without full re-render\n if (this.listboxRef) {\n // Remove previous highlight\n if (prevIndex >= 0) {\n const prevEl = this.listboxRef.querySelector(`[data-index=\"${prevIndex}\"]`)\n prevEl?.classList.remove('highlighted')\n }\n // Add new highlight\n const newEl = this.listboxRef.querySelector(`[data-index=\"${index}\"]`)\n newEl?.classList.add('highlighted')\n\n // Update aria-activedescendant on input\n if (this.inputRef) {\n this.inputRef.setAttribute(\n 'aria-activedescendant',\n `${this.instanceId}-option-${index}`\n )\n }\n\n // Scroll into view (check if method exists for jsdom compatibility)\n if (newEl && typeof (newEl as HTMLElement).scrollIntoView === 'function') {\n ;(newEl as HTMLElement).scrollIntoView({ block: 'nearest' })\n }\n }\n\n const option = this.state.filteredOptions[index]\n this.callbacks.onHighlight?.(option, this.state)\n }\n\n // ===========================================================================\n // Static Field Renderer\n // ===========================================================================\n\n /**\n * コンボボックスフィールドをHTMLとしてレンダリング(静的メソッド)\n * SSR/初期レンダリング用\n *\n * @param field - コンボボックスフィールド定義\n * @returns 生成されたHTML文字列\n */\n static renderField(field: ComboboxField): string {\n const attrs: string[] = [\n `id=\"${escapeHtml(field.id)}\"`,\n `name=\"${escapeHtml(field.id)}\"`,\n 'role=\"combobox\"',\n 'aria-haspopup=\"listbox\"',\n 'aria-expanded=\"false\"',\n ]\n\n if (field.required) {\n attrs.push('required')\n }\n if (field.disabled) {\n attrs.push('disabled')\n }\n if (field.placeholder) {\n attrs.push(`placeholder=\"${escapeHtml(field.placeholder)}\"`)\n }\n\n const options = getOptions(field.options ?? [])\n const optionListId = `${field.id}-listbox`\n attrs.push(`aria-controls=\"${optionListId}\"`)\n\n // オプションリストをhidden datalistとして準備\n const optionHtml = options\n .map((opt, index) => {\n const disabled = opt.disabled ? 'aria-disabled=\"true\"' : ''\n return `\n <div\n role=\"option\"\n id=\"${escapeHtml(field.id)}-option-${index}\"\n data-value=\"${escapeHtml(String(opt.value))}\"\n ${disabled}\n >\n ${escapeHtml(opt.label)}\n </div>\n `\n })\n .join('')\n\n const content = `\n <div class=\"combobox-wrapper\" data-state=\"closed\">\n <div class=\"combobox-control\">\n <input type=\"text\" class=\"combobox-input\" ${attrs.join(' ')} />\n <button type=\"button\" class=\"combobox-dropdown-indicator\" aria-label=\"Open options\">▼</button>\n </div>\n <div role=\"listbox\" id=\"${optionListId}\" class=\"combobox-dropdown\" hidden>\n ${optionHtml}\n </div>\n </div>\n `\n return createFieldWrapper(field, content)\n }\n}\n","/**\n * Heading Component\n * 見出しコンポーネント\n *\n * \n * - セマンティックレベル(h1-h6)と視覚的サイズの分離\n * - アクセシビリティを考慮した構造\n * - カラーバリエーション対応\n * - テキスト配置オプション\n */\n\nimport { createElement, generateId } from '../utils/dom'\nimport { escapeHtml, getDefaultSizeForLevel } from '../utils/field-helpers'\nimport type { HeadingField } from '../../types/schema'\n\n// =============================================================================\n// Types\n// =============================================================================\n\n/**\n * 見出しの状態\n */\nexport interface HeadingState {\n /** 見出しレベル */\n level: 1 | 2 | 3 | 4 | 5 | 6\n /** 見出しテキスト */\n text: string\n /** サイズバリアント */\n size?: 'xs' | 'sm' | 'md' | 'lg' | 'xl' | '2xl'\n /** テキスト配置 */\n align?: 'left' | 'center' | 'right'\n /** カラーバリエーション */\n color?: 'default' | 'primary' | 'secondary' | 'muted' | 'danger' | 'success' | 'warning'\n /** アイコン */\n icon?: string\n}\n\n/**\n * 見出しのコールバック(拡張用)\n */\nexport interface HeadingCallbacks {\n /** クリック時(インタラクティブな見出しの場合) */\n onClick?: (state: HeadingState) => void\n}\n\n/**\n * 見出しの設定\n */\nexport interface HeadingConfig {\n /** 見出しレベル(h1-h6) */\n level: 1 | 2 | 3 | 4 | 5 | 6\n /** 見出しテキスト */\n text: string\n /** サイズバリアント(デフォルト: levelに基づく) */\n size?: 'xs' | 'sm' | 'md' | 'lg' | 'xl' | '2xl'\n /** テキスト配置(デフォルト: left) */\n align?: 'left' | 'center' | 'right'\n /** カラーバリエーション(デフォルト: default) */\n color?: 'default' | 'primary' | 'secondary' | 'muted' | 'danger' | 'success' | 'warning'\n /** アイコン(オプション) */\n icon?: string\n /** ID属性 */\n id?: string\n /** カスタムCSSクラス */\n className?: string\n}\n\n// =============================================================================\n// Heading Class\n// =============================================================================\n\n/**\n * 見出しコンポーネント\n */\nexport class Heading {\n private config: HeadingConfig\n private state: HeadingState\n private callbacks: HeadingCallbacks\n private container: HTMLElement\n private instanceId: string\n\n constructor(\n container: HTMLElement,\n config: HeadingConfig,\n callbacks: HeadingCallbacks = {}\n ) {\n this.config = config\n this.container = container\n this.callbacks = callbacks\n this.instanceId = config.id ?? generateId('heading')\n this.state = this.createInitialState()\n }\n\n // ===========================================================================\n // Public Methods\n // ===========================================================================\n\n /**\n * 見出しをレンダリング\n */\n render(): void {\n this.container.innerHTML = ''\n\n const level = this.state.level\n const size = this.state.size ?? this.getDefaultSizeForLevel(level)\n const align = this.state.align ?? 'left'\n const color = this.state.color ?? 'default'\n\n // コンテナに基本クラスとバリアントクラスを追加\n this.container.className = [\n 'mokkun-heading',\n `heading-level-${level}`,\n `heading-size-${size}`,\n `heading-align-${align}`,\n `heading-color-${color}`,\n this.config.className ?? '',\n ]\n .filter(Boolean)\n .join(' ')\n\n // 見出し要素を作成\n const headingElement = this.createHeadingElement()\n this.container.appendChild(headingElement)\n }\n\n /**\n * 見出しテキストを更新\n */\n setText(text: string): void {\n this.state = {\n ...this.state,\n text,\n }\n this.render()\n }\n\n /**\n * 見出しレベルを更新\n */\n setLevel(level: 1 | 2 | 3 | 4 | 5 | 6): void {\n this.state = {\n ...this.state,\n level,\n }\n this.render()\n }\n\n /**\n * サイズバリアントを更新\n */\n setSize(size: 'xs' | 'sm' | 'md' | 'lg' | 'xl' | '2xl'): void {\n this.state = {\n ...this.state,\n size,\n }\n this.render()\n }\n\n /**\n * テキスト配置を更新\n */\n setAlign(align: 'left' | 'center' | 'right'): void {\n this.state = {\n ...this.state,\n align,\n }\n this.render()\n }\n\n /**\n * カラーバリエーションを更新\n */\n setColor(\n color: 'default' | 'primary' | 'secondary' | 'muted' | 'danger' | 'success' | 'warning'\n ): void {\n this.state = {\n ...this.state,\n color,\n }\n this.render()\n }\n\n /**\n * 現在の状態を取得\n */\n getState(): HeadingState {\n return { ...this.state }\n }\n\n // ===========================================================================\n // Private Methods\n // ===========================================================================\n\n /**\n * 初期状態を作成\n */\n private createInitialState(): HeadingState {\n return {\n level: this.config.level,\n text: this.config.text,\n size: this.config.size,\n align: this.config.align,\n color: this.config.color,\n icon: this.config.icon,\n }\n }\n\n /**\n * 見出し要素を作成\n */\n private createHeadingElement(): HTMLElement {\n const tag = `h${this.state.level}` as keyof HTMLElementTagNameMap\n const headingElement = createElement(tag, {\n className: 'heading-element',\n attributes: {\n id: this.instanceId,\n },\n })\n\n // アイコンがある場合\n if (this.state.icon) {\n const iconSpan = createElement('span', {\n className: 'heading-icon',\n textContent: this.state.icon,\n })\n headingElement.appendChild(iconSpan)\n }\n\n // テキスト\n const textSpan = createElement('span', {\n className: 'heading-text',\n textContent: this.state.text,\n })\n headingElement.appendChild(textSpan)\n\n // クリックイベント(オプション)\n if (this.callbacks.onClick) {\n headingElement.style.cursor = 'pointer'\n headingElement.addEventListener('click', () => {\n this.callbacks.onClick?.(this.getState())\n })\n }\n\n return headingElement\n }\n\n /**\n * レベルに基づくデフォルトサイズを取得\n */\n private getDefaultSizeForLevel(level: 1 | 2 | 3 | 4 | 5 | 6): 'xs' | 'sm' | 'md' | 'lg' | 'xl' | '2xl' {\n return getDefaultSizeForLevel(level)\n }\n\n // ===========================================================================\n // Static Field Renderer\n // ===========================================================================\n\n /**\n * 見出しフィールドをHTMLとしてレンダリング(静的メソッド)\n * SSR/初期レンダリング用\n *\n * @param field - 見出しフィールド定義\n * @returns 生成されたHTML文字列\n */\n static renderField(field: HeadingField): string {\n const size = field.size ?? getDefaultSizeForLevel(field.level)\n const align = field.align ?? 'left'\n const color = field.color ?? 'default'\n const tag = `h${field.level}`\n\n const classes = [\n 'heading-field-container',\n `heading-level-${field.level}`,\n `heading-size-${size}`,\n `heading-align-${align}`,\n `heading-color-${color}`,\n ]\n\n if (field.class) {\n classes.push(field.class)\n }\n\n const iconHtml = field.icon ? `<span class=\"heading-icon\">${escapeHtml(field.icon)}</span>` : ''\n\n // 見出しフィールドはラベルや説明が不要なため、直接コンテンツを返す\n return `\n <div class=\"${classes.join(' ')}\" data-field-id=\"${escapeHtml(field.id)}\">\n <${tag} class=\"heading-element\" id=\"${escapeHtml(field.id)}\">\n ${iconHtml}\n <span class=\"heading-text\">${escapeHtml(field.text)}</span>\n </${tag}>\n </div>\n `\n }\n}\n\n// =============================================================================\n// Factory Function\n// =============================================================================\n\n/**\n * 見出しコンポーネントを作成\n */\nexport function createHeading(\n container: HTMLElement,\n config: HeadingConfig,\n callbacks?: HeadingCallbacks\n): Heading {\n const heading = new Heading(container, config, callbacks)\n heading.render()\n return heading\n}\n","/**\n * Duration Picker Component\n * 期間選択コンポーネント(時間:分 等の選択UI)\n *\n * 機能:\n * - 複数の時間単位(日/時間/分/秒)からの選択\n * - 柔軟な単位設定\n * - アクセシビリティ対応\n */\n\nimport { createElement, generateId } from '../utils/dom'\nimport {\n escapeHtml,\n createFieldWrapper,\n unitLabels,\n} from '../utils/field-helpers'\nimport type { DurationPickerField } from '../../types/schema'\n\n// =============================================================================\n// Types\n// =============================================================================\n\n/**\n * 時間単位\n */\nexport type DurationUnit = 'days' | 'hours' | 'minutes' | 'seconds'\n\n/**\n * Duration Pickerの状態\n */\nexport interface DurationPickerState {\n /** 各単位の値 */\n values: Record<DurationUnit, number>\n /** 無効化状態 */\n disabled: boolean\n}\n\n/**\n * Duration Pickerのコールバック\n */\nexport interface DurationPickerCallbacks {\n /** 値変更時 */\n onChange?: (values: Record<DurationUnit, number>, state: DurationPickerState) => void\n}\n\n/**\n * Duration Pickerの設定\n */\nexport interface DurationPickerConfig {\n /** 使用する単位 */\n units: DurationUnit[]\n /** 初期値 */\n defaultValues?: Partial<Record<DurationUnit, number>>\n /** 無効化 */\n disabled?: boolean\n /** name属性プレフィックス */\n name?: string\n /** ID */\n id?: string\n}\n\n// =============================================================================\n// DurationPicker Class\n// =============================================================================\n\n/**\n * 期間選択コンポーネント\n */\nexport class DurationPicker {\n private config: DurationPickerConfig\n private state: DurationPickerState\n private callbacks: DurationPickerCallbacks\n private container: HTMLElement\n private instanceId: string\n\n constructor(\n container: HTMLElement,\n config: DurationPickerConfig,\n callbacks: DurationPickerCallbacks = {}\n ) {\n this.config = config\n this.container = container\n this.callbacks = callbacks\n this.instanceId = config.id ?? generateId('duration-picker')\n this.state = this.createInitialState()\n }\n\n // ===========================================================================\n // Public Methods\n // ===========================================================================\n\n /**\n * Duration Pickerをレンダリング\n */\n render(): void {\n this.container.innerHTML = ''\n\n const wrapper = createElement('div', {\n className: 'mokkun-duration-picker',\n })\n\n if (this.state.disabled) {\n wrapper.classList.add('is-disabled')\n }\n\n // 各単位のセレクター\n for (const unit of this.config.units) {\n const unitElement = this.renderUnitSelector(unit)\n wrapper.appendChild(unitElement)\n }\n\n this.container.appendChild(wrapper)\n }\n\n /**\n * 値を設定\n */\n setValue(unit: DurationUnit, value: number): void {\n if (this.state.disabled) {\n return\n }\n\n this.state = {\n ...this.state,\n values: {\n ...this.state.values,\n [unit]: value,\n },\n }\n\n this.render()\n this.callbacks.onChange?.(this.state.values, this.state)\n }\n\n /**\n * 全ての値を設定\n */\n setValues(values: Partial<Record<DurationUnit, number>>): void {\n if (this.state.disabled) {\n return\n }\n\n this.state = {\n ...this.state,\n values: {\n ...this.state.values,\n ...values,\n },\n }\n\n this.render()\n this.callbacks.onChange?.(this.state.values, this.state)\n }\n\n /**\n * 値を取得\n */\n getValue(unit: DurationUnit): number {\n return this.state.values[unit]\n }\n\n /**\n * 全ての値を取得\n */\n getValues(): Record<DurationUnit, number> {\n return { ...this.state.values }\n }\n\n /**\n * 無効化状態を設定\n */\n setDisabled(disabled: boolean): void {\n if (this.state.disabled === disabled) {\n return\n }\n\n this.state = {\n ...this.state,\n disabled,\n }\n\n this.render()\n }\n\n /**\n * 現在の状態を取得\n */\n getState(): DurationPickerState {\n return { ...this.state }\n }\n\n // ===========================================================================\n // Private Methods\n // ===========================================================================\n\n /**\n * 初期状態を作成\n */\n private createInitialState(): DurationPickerState {\n const defaultValues = this.config.defaultValues ?? {}\n return {\n values: {\n days: defaultValues.days ?? 0,\n hours: defaultValues.hours ?? 0,\n minutes: defaultValues.minutes ?? 0,\n seconds: defaultValues.seconds ?? 0,\n },\n disabled: this.config.disabled ?? false,\n }\n }\n\n /**\n * 単位セレクターをレンダリング\n */\n private renderUnitSelector(unit: DurationUnit): HTMLElement {\n const unitContainer = createElement('div', {\n className: 'duration-unit',\n })\n\n const unitId = `${this.instanceId}-${unit}`\n const max = this.getMaxForUnit(unit)\n const currentValue = this.state.values[unit]\n\n // セレクトボックス\n const select = createElement('select', {\n className: 'form-select duration-select',\n attributes: {\n id: unitId,\n name: this.config.name ? `${this.config.name}-${unit}` : unitId,\n },\n })\n\n if (this.state.disabled) {\n select.setAttribute('disabled', 'disabled')\n }\n\n // オプションを生成\n for (let i = 0; i <= max; i++) {\n const option = createElement('option', {\n textContent: String(i),\n })\n option.setAttribute('value', String(i))\n if (i === currentValue) {\n option.setAttribute('selected', 'selected')\n }\n select.appendChild(option)\n }\n\n // 変更イベント\n select.addEventListener('change', (e) => {\n const target = e.target as HTMLSelectElement\n this.setValue(unit, parseInt(target.value, 10))\n })\n\n unitContainer.appendChild(select)\n\n // 単位ラベル\n const label = createElement('span', {\n className: 'duration-unit-label',\n textContent: unitLabels[unit] ?? unit,\n })\n unitContainer.appendChild(label)\n\n return unitContainer\n }\n\n /**\n * 単位ごとの最大値を取得\n */\n private getMaxForUnit(unit: DurationUnit): number {\n switch (unit) {\n case 'days':\n return 365\n case 'hours':\n return 23\n case 'minutes':\n case 'seconds':\n return 59\n default:\n return 59\n }\n }\n\n // ===========================================================================\n // Static Field Renderer\n // ===========================================================================\n\n /**\n * Duration Pickerフィールドを HTMLとしてレンダリング(静的メソッド)\n * SSR/初期レンダリング用\n *\n * @param field - Duration Pickerフィールド定義\n * @returns 生成されたHTML文字列\n */\n static renderField(field: DurationPickerField): string {\n const units = field.units ?? ['hours', 'minutes']\n const fieldId = field.id\n\n const selectors = units\n .map((unit) => {\n const unitId = `${fieldId}-${unit}`\n let max = 59\n if (unit === 'hours') max = 23\n if (unit === 'days') max = 365\n\n const options = Array.from({ length: max + 1 }, (_, i) =>\n `<option value=\"${i}\">${i}</option>`\n ).join('')\n\n return `\n <div class=\"duration-unit\">\n <select id=\"${escapeHtml(unitId)}\" name=\"${escapeHtml(unitId)}\" class=\"form-select duration-select\" ${field.disabled ? 'disabled' : ''}>\n ${options}\n </select>\n <span class=\"duration-unit-label\">${unitLabels[unit] ?? unit}</span>\n </div>\n `\n })\n .join('')\n\n const content = `<div class=\"duration-picker\">${selectors}</div>`\n return createFieldWrapper(field, content)\n }\n}\n\n// =============================================================================\n// Factory Function\n// =============================================================================\n\n/**\n * Duration Pickerを作成するファクトリ関数\n */\nexport function createDurationPicker(\n container: HTMLElement,\n config: DurationPickerConfig,\n callbacks: DurationPickerCallbacks = {}\n): DurationPicker {\n const picker = new DurationPicker(container, config, callbacks)\n picker.render()\n return picker\n}\n","/**\n * Duration Input Component\n * 期間入力コンポーネント(数値入力 + 単位表示)\n *\n * 機能:\n * - 数値入力による期間指定\n * - 単位ラベル表示\n * - バリデーション\n * - アクセシビリティ対応\n */\n\nimport { createElement, generateId } from '../utils/dom'\nimport {\n createFieldWrapper,\n getCommonAttributes,\n unitLabels,\n} from '../utils/field-helpers'\nimport type { DurationInputField } from '../../types/schema'\n\n// =============================================================================\n// Types\n// =============================================================================\n\n/**\n * 表示単位\n */\nexport type DisplayUnit = 'hours' | 'minutes' | 'seconds'\n\n/**\n * Duration Inputの状態\n */\nexport interface DurationInputState {\n /** 現在の値(表示単位での数値) */\n value: number\n /** 無効化状態 */\n disabled: boolean\n /** 読み取り専用状態 */\n readonly: boolean\n /** エラー状態 */\n error: boolean\n /** エラーメッセージ */\n errorMessage?: string\n}\n\n/**\n * Duration Inputのコールバック\n */\nexport interface DurationInputCallbacks {\n /** 値変更時 */\n onChange?: (value: number, state: DurationInputState) => void\n /** フォーカス時 */\n onFocus?: (state: DurationInputState) => void\n /** ブラー時 */\n onBlur?: (state: DurationInputState) => void\n}\n\n/**\n * Duration Inputの設定\n */\nexport interface DurationInputConfig {\n /** 初期値 */\n defaultValue?: number\n /** 表示単位 */\n displayUnit?: DisplayUnit\n /** 最小値 */\n min?: number\n /** 最大値 */\n max?: number\n /** 無効化 */\n disabled?: boolean\n /** 読み取り専用 */\n readonly?: boolean\n /** 必須 */\n required?: boolean\n /** name属性 */\n name?: string\n /** ID */\n id?: string\n /** プレースホルダー */\n placeholder?: string\n}\n\n// =============================================================================\n// DurationInput Class\n// =============================================================================\n\n/**\n * 期間入力コンポーネント\n */\nexport class DurationInput {\n private config: DurationInputConfig\n private state: DurationInputState\n private callbacks: DurationInputCallbacks\n private container: HTMLElement\n private instanceId: string\n private inputElement: HTMLInputElement | null = null\n\n constructor(\n container: HTMLElement,\n config: DurationInputConfig = {},\n callbacks: DurationInputCallbacks = {}\n ) {\n this.config = config\n this.container = container\n this.callbacks = callbacks\n this.instanceId = config.id ?? generateId('duration-input')\n this.state = this.createInitialState()\n }\n\n // ===========================================================================\n // Public Methods\n // ===========================================================================\n\n /**\n * Duration Inputをレンダリング\n */\n render(): void {\n this.container.innerHTML = ''\n\n const wrapper = createElement('div', {\n className: 'mokkun-duration-input',\n })\n\n if (this.state.disabled) {\n wrapper.classList.add('is-disabled')\n }\n if (this.state.readonly) {\n wrapper.classList.add('is-readonly')\n }\n if (this.state.error) {\n wrapper.classList.add('has-error')\n }\n\n // 入力グループ(input + 単位)\n const inputGroup = this.renderInputGroup()\n wrapper.appendChild(inputGroup)\n\n // エラーメッセージ\n if (this.state.error && this.state.errorMessage) {\n const errorEl = this.renderError()\n wrapper.appendChild(errorEl)\n }\n\n this.container.appendChild(wrapper)\n }\n\n /**\n * 値を設定\n */\n setValue(value: number): void {\n if (this.state.value === value) {\n return\n }\n\n this.state = {\n ...this.state,\n value,\n }\n\n if (this.inputElement) {\n this.inputElement.value = String(value)\n }\n\n this.callbacks.onChange?.(value, this.state)\n }\n\n /**\n * 値を取得\n */\n getValue(): number {\n return this.state.value\n }\n\n /**\n * エラー状態を設定\n */\n setError(error: boolean, errorMessage?: string): void {\n this.state = {\n ...this.state,\n error,\n errorMessage,\n }\n\n this.render()\n }\n\n /**\n * 無効化状態を設定\n */\n setDisabled(disabled: boolean): void {\n if (this.state.disabled === disabled) {\n return\n }\n\n this.state = {\n ...this.state,\n disabled,\n }\n\n this.render()\n }\n\n /**\n * 読み取り専用状態を設定\n */\n setReadonly(readonly: boolean): void {\n if (this.state.readonly === readonly) {\n return\n }\n\n this.state = {\n ...this.state,\n readonly,\n }\n\n this.render()\n }\n\n /**\n * フォーカス\n */\n focus(): void {\n this.inputElement?.focus()\n }\n\n /**\n * ブラー\n */\n blur(): void {\n this.inputElement?.blur()\n }\n\n /**\n * 現在の状態を取得\n */\n getState(): DurationInputState {\n return { ...this.state }\n }\n\n // ===========================================================================\n // Private Methods\n // ===========================================================================\n\n /**\n * 初期状態を作成\n */\n private createInitialState(): DurationInputState {\n return {\n value: this.config.defaultValue ?? 0,\n disabled: this.config.disabled ?? false,\n readonly: this.config.readonly ?? false,\n error: false,\n errorMessage: undefined,\n }\n }\n\n /**\n * 入力グループをレンダリング\n */\n private renderInputGroup(): HTMLElement {\n const inputGroup = createElement('div', {\n className: 'input-with-unit',\n })\n\n // 数値入力\n const input = this.renderInput()\n inputGroup.appendChild(input)\n\n // 単位ラベル\n const unit = this.config.displayUnit ?? 'minutes'\n const unitLabel = createElement('span', {\n className: 'input-unit',\n textContent: unitLabels[unit] ?? unit,\n })\n inputGroup.appendChild(unitLabel)\n\n return inputGroup\n }\n\n /**\n * 入力フィールドをレンダリング\n */\n private renderInput(): HTMLInputElement {\n const input = createElement('input', {\n className: 'form-input duration-input-field',\n attributes: {\n type: 'number',\n id: this.instanceId,\n name: this.config.name ?? this.instanceId,\n min: String(this.config.min ?? 0),\n ...(this.config.max !== undefined && { max: String(this.config.max) }),\n ...(this.config.placeholder && { placeholder: this.config.placeholder }),\n ...(this.config.required && { required: 'required' }),\n ...(this.state.disabled && { disabled: 'disabled' }),\n ...(this.state.readonly && { readonly: 'readonly' }),\n ...(this.state.error && { 'aria-invalid': 'true' }),\n },\n }) as HTMLInputElement\n\n input.value = String(this.state.value)\n\n // イベントリスナー\n input.addEventListener('input', this.handleInput.bind(this))\n input.addEventListener('focus', this.handleFocus.bind(this))\n input.addEventListener('blur', this.handleBlur.bind(this))\n\n this.inputElement = input\n return input\n }\n\n /**\n * エラーメッセージをレンダリング\n */\n private renderError(): HTMLElement {\n return createElement('div', {\n className: 'duration-input-error',\n textContent: this.state.errorMessage ?? '',\n attributes: {\n id: `${this.instanceId}-error`,\n role: 'alert',\n },\n })\n }\n\n // ===========================================================================\n // Event Handlers\n // ===========================================================================\n\n /**\n * 入力イベント\n */\n private handleInput(event: Event): void {\n const target = event.target as HTMLInputElement\n const value = parseInt(target.value, 10) || 0\n\n this.state = {\n ...this.state,\n value,\n }\n\n this.callbacks.onChange?.(value, this.state)\n }\n\n /**\n * フォーカスイベント\n */\n private handleFocus(): void {\n this.callbacks.onFocus?.(this.state)\n }\n\n /**\n * ブラーイベント\n */\n private handleBlur(): void {\n this.callbacks.onBlur?.(this.state)\n }\n\n // ===========================================================================\n // Static Field Renderer\n // ===========================================================================\n\n /**\n * Duration Inputフィールドを HTMLとしてレンダリング(静的メソッド)\n * SSR/初期レンダリング用\n *\n * @param field - Duration Inputフィールド定義\n * @returns 生成されたHTML文字列\n */\n static renderField(field: DurationInputField): string {\n const attrs: string[] = [getCommonAttributes(field)]\n attrs.push('min=\"0\"')\n\n if (field.default !== undefined) {\n attrs.push(`value=\"${field.default}\"`)\n }\n\n const unit = field.display_unit ?? 'minutes'\n\n const content = `\n <div class=\"input-with-unit\">\n <input type=\"number\" class=\"form-input\" ${attrs.join(' ')} />\n <span class=\"input-unit\">${unitLabels[unit] ?? unit}</span>\n </div>\n `\n return createFieldWrapper(field, content)\n }\n}\n\n// =============================================================================\n// Factory Function\n// =============================================================================\n\n/**\n * Duration Inputを作成するファクトリ関数\n */\nexport function createDurationInput(\n container: HTMLElement,\n config: DurationInputConfig = {},\n callbacks: DurationInputCallbacks = {}\n): DurationInput {\n const durationInput = new DurationInput(container, config, callbacks)\n durationInput.render()\n return durationInput\n}\n","/**\n * Pagination Component\n * ページネーションコンポーネント\n *\n * 機能:\n * - ページ番号表示\n * - 前後ボタン\n * - 最初/最後へのジャンプ\n * - ページサイズ選択\n * - 表示件数表示\n * - コンパクト表示モード\n */\n\nimport { createElement, generateId } from '../utils/dom'\nimport { createFieldWrapper } from '../utils/field-helpers'\nimport type { InputField } from '../../types/schema'\n\n// =============================================================================\n// Types\n// =============================================================================\n\n/**\n * ページネーションの状態\n */\nexport interface PaginationState {\n /** 現在のページ(1始まり) */\n currentPage: number\n /** 1ページあたりのアイテム数 */\n pageSize: number\n /** 総アイテム数 */\n totalItems: number\n /** 総ページ数 */\n totalPages: number\n}\n\n/**\n * ページネーションのコールバック\n */\nexport interface PaginationCallbacks {\n /** ページ変更時 */\n onPageChange?: (page: number, state: PaginationState) => void\n /** ページサイズ変更時 */\n onPageSizeChange?: (pageSize: number, state: PaginationState) => void\n}\n\n/**\n * ページネーションの設定\n */\nexport interface PaginationConfig {\n /** 総アイテム数 */\n totalItems: number\n /** 初期ページ(1始まり、デフォルト: 1) */\n initialPage?: number\n /** 初期ページサイズ(デフォルト: 10) */\n initialPageSize?: number\n /** ページサイズの選択肢(デフォルト: [10, 25, 50, 100]) */\n pageSizeOptions?: number[]\n /** ページサイズ選択を表示するか(デフォルト: true) */\n showPageSizeSelector?: boolean\n /** 表示件数を表示するか(デフォルト: true) */\n showItemCount?: boolean\n /** 最初/最後へのジャンプボタンを表示するか(デフォルト: true) */\n showJumpButtons?: boolean\n /** ページ番号ボタンの最大表示数(デフォルト: 7) */\n maxPageButtons?: number\n /** コンパクトモード(デフォルト: false) */\n compact?: boolean\n /** 位置(デフォルト: 'center') */\n align?: 'left' | 'center' | 'right'\n}\n\n// =============================================================================\n// Pagination Class\n// =============================================================================\n\n/**\n * ページネーションコンポーネント\n */\nexport class Pagination {\n private config: PaginationConfig\n private state: PaginationState\n private callbacks: PaginationCallbacks\n private container: HTMLElement\n private instanceId: string\n\n constructor(\n container: HTMLElement,\n config: PaginationConfig,\n callbacks: PaginationCallbacks = {}\n ) {\n this.config = config\n this.container = container\n this.callbacks = callbacks\n this.instanceId = generateId('pagination')\n this.state = this.createInitialState()\n }\n\n // ===========================================================================\n // Public Methods\n // ===========================================================================\n\n /**\n * ページネーションをレンダリング\n */\n render(): void {\n this.container.innerHTML = ''\n\n const align = this.config.align ?? 'center'\n const compact = this.config.compact ?? false\n this.container.className = `mokkun-pagination pagination-align-${align} ${compact ? 'pagination-compact' : ''}`\n\n const wrapper = createElement('div', { className: 'pagination-wrapper' })\n\n // ページサイズ選択\n if (this.config.showPageSizeSelector !== false) {\n const pageSizeSelector = this.renderPageSizeSelector()\n wrapper.appendChild(pageSizeSelector)\n }\n\n // ページナビゲーション\n const navigation = this.renderNavigation()\n wrapper.appendChild(navigation)\n\n // 表示件数\n if (this.config.showItemCount !== false) {\n const itemCount = this.renderItemCount()\n wrapper.appendChild(itemCount)\n }\n\n this.container.appendChild(wrapper)\n }\n\n /**\n * 指定したページへ移動\n */\n goToPage(page: number): void {\n const newPage = this.clampPage(page)\n if (this.state.currentPage === newPage) {\n return\n }\n\n this.state = {\n ...this.state,\n currentPage: newPage,\n }\n\n this.render()\n this.callbacks.onPageChange?.(newPage, this.state)\n }\n\n /**\n * 次のページへ移動\n */\n nextPage(): void {\n this.goToPage(this.state.currentPage + 1)\n }\n\n /**\n * 前のページへ移動\n */\n previousPage(): void {\n this.goToPage(this.state.currentPage - 1)\n }\n\n /**\n * 最初のページへ移動\n */\n firstPage(): void {\n this.goToPage(1)\n }\n\n /**\n * 最後のページへ移動\n */\n lastPage(): void {\n this.goToPage(this.state.totalPages)\n }\n\n /**\n * ページサイズを設定\n */\n setPageSize(pageSize: number): void {\n if (this.state.pageSize === pageSize) {\n return\n }\n\n // 現在表示している最初のアイテムのインデックスを保持\n const firstItemIndex = (this.state.currentPage - 1) * this.state.pageSize\n\n // 新しいページサイズで同じアイテムが表示されるページを計算\n const newPage = Math.floor(firstItemIndex / pageSize) + 1\n\n const totalPages = Math.ceil(this.state.totalItems / pageSize)\n\n this.state = {\n ...this.state,\n pageSize,\n totalPages,\n currentPage: this.clampPage(newPage, totalPages),\n }\n\n this.render()\n this.callbacks.onPageSizeChange?.(pageSize, this.state)\n }\n\n /**\n * 総アイテム数を更新\n */\n setTotalItems(totalItems: number): void {\n const totalPages = Math.ceil(totalItems / this.state.pageSize)\n\n this.state = {\n ...this.state,\n totalItems,\n totalPages,\n currentPage: this.clampPage(this.state.currentPage, totalPages),\n }\n\n this.render()\n }\n\n /**\n * 現在の状態を取得\n */\n getState(): PaginationState {\n return { ...this.state }\n }\n\n /**\n * 現在のページを取得\n */\n getCurrentPage(): number {\n return this.state.currentPage\n }\n\n /**\n * ページサイズを取得\n */\n getPageSize(): number {\n return this.state.pageSize\n }\n\n /**\n * 表示中のアイテム範囲を取得\n */\n getItemRange(): { start: number; end: number } {\n const start = (this.state.currentPage - 1) * this.state.pageSize + 1\n const end = Math.min(this.state.currentPage * this.state.pageSize, this.state.totalItems)\n return { start, end }\n }\n\n // ===========================================================================\n // Private Methods\n // ===========================================================================\n\n /**\n * 初期状態を作成\n */\n private createInitialState(): PaginationState {\n const pageSize = this.config.initialPageSize ?? 10\n const totalPages = Math.ceil(this.config.totalItems / pageSize)\n const currentPage = this.clampPage(this.config.initialPage ?? 1, totalPages)\n\n return {\n currentPage,\n pageSize,\n totalItems: this.config.totalItems,\n totalPages,\n }\n }\n\n /**\n * ページ番号を有効範囲内にクランプ\n */\n private clampPage(page: number, totalPages?: number): number {\n const maxPage = totalPages ?? this.state.totalPages\n return Math.max(1, Math.min(page, maxPage))\n }\n\n /**\n * ページサイズセレクターをレンダリング\n */\n private renderPageSizeSelector(): HTMLElement {\n const container = createElement('div', { className: 'pagination-page-size-selector' })\n\n const label = createElement('label', {\n className: 'page-size-label',\n textContent: '表示件数:',\n attributes: {\n for: `${this.instanceId}-page-size`,\n },\n })\n\n const select = createElement('select', {\n className: 'page-size-select',\n attributes: {\n id: `${this.instanceId}-page-size`,\n 'aria-label': 'ページサイズ選択',\n },\n }) as HTMLSelectElement\n\n const options = this.config.pageSizeOptions ?? [10, 25, 50, 100]\n options.forEach(size => {\n const option = createElement('option', {\n textContent: `${size}件`,\n attributes: {\n value: String(size),\n },\n }) as HTMLOptionElement\n\n if (size === this.state.pageSize) {\n option.selected = true\n }\n\n select.appendChild(option)\n })\n\n select.addEventListener('change', (e) => {\n const target = e.target as HTMLSelectElement\n this.setPageSize(parseInt(target.value, 10))\n })\n\n container.appendChild(label)\n container.appendChild(select)\n\n return container\n }\n\n /**\n * ナビゲーションをレンダリング\n */\n private renderNavigation(): HTMLElement {\n const container = createElement('div', { className: 'pagination-navigation' })\n\n const { currentPage, totalPages } = this.state\n const showJumpButtons = this.config.showJumpButtons !== false\n\n // 最初へボタン\n if (showJumpButtons) {\n const firstButton = this.createButton('最初', 'first', currentPage === 1)\n firstButton.addEventListener('click', () => this.firstPage())\n container.appendChild(firstButton)\n }\n\n // 前へボタン\n const prevButton = this.createButton('前へ', 'prev', currentPage === 1)\n prevButton.addEventListener('click', () => this.previousPage())\n container.appendChild(prevButton)\n\n // ページ番号ボタン\n const pageButtons = this.renderPageButtons()\n pageButtons.forEach(button => container.appendChild(button))\n\n // 次へボタン\n const nextButton = this.createButton('次へ', 'next', currentPage === totalPages)\n nextButton.addEventListener('click', () => this.nextPage())\n container.appendChild(nextButton)\n\n // 最後へボタン\n if (showJumpButtons) {\n const lastButton = this.createButton('最後', 'last', currentPage === totalPages)\n lastButton.addEventListener('click', () => this.lastPage())\n container.appendChild(lastButton)\n }\n\n return container\n }\n\n /**\n * ページ番号ボタンをレンダリング\n */\n private renderPageButtons(): HTMLElement[] {\n const { currentPage, totalPages } = this.state\n const maxButtons = this.config.maxPageButtons ?? 7\n\n if (totalPages === 0) {\n return []\n }\n\n const buttons: HTMLElement[] = []\n const pages = this.calculateVisiblePages(currentPage, totalPages, maxButtons)\n\n let previousPage = 0\n pages.forEach(page => {\n // 省略記号を追加\n if (previousPage > 0 && page > previousPage + 1) {\n const ellipsis = createElement('span', {\n className: 'pagination-ellipsis',\n textContent: '...',\n attributes: {\n 'aria-hidden': 'true',\n },\n })\n buttons.push(ellipsis)\n }\n\n const button = this.createPageButton(page, page === currentPage)\n button.addEventListener('click', () => this.goToPage(page))\n buttons.push(button)\n\n previousPage = page\n })\n\n return buttons\n }\n\n /**\n * 表示するページ番号を計算\n */\n private calculateVisiblePages(currentPage: number, totalPages: number, maxButtons: number): number[] {\n if (totalPages <= maxButtons) {\n return Array.from({ length: totalPages }, (_, i) => i + 1)\n }\n\n const pages: number[] = []\n const sideButtons = Math.floor((maxButtons - 3) / 2) // 3 = 最初 + 最後 + 現在\n\n // 常に最初のページを含める\n pages.push(1)\n\n if (currentPage <= sideButtons + 2) {\n // 先頭に近い場合\n for (let i = 2; i < maxButtons - 1; i++) {\n pages.push(i)\n }\n } else if (currentPage >= totalPages - sideButtons - 1) {\n // 末尾に近い場合\n for (let i = totalPages - maxButtons + 2; i < totalPages; i++) {\n pages.push(i)\n }\n } else {\n // 中央の場合\n for (let i = currentPage - sideButtons; i <= currentPage + sideButtons; i++) {\n if (i > 1 && i < totalPages) {\n pages.push(i)\n }\n }\n }\n\n // 常に最後のページを含める(totalPages > 1の場合)\n if (totalPages > 1 && !pages.includes(totalPages)) {\n pages.push(totalPages)\n }\n\n return pages.sort((a, b) => a - b)\n }\n\n /**\n * ボタンを作成\n */\n private createButton(label: string, type: string, disabled: boolean): HTMLElement {\n const button = createElement('button', {\n className: `pagination-button pagination-button-${type}`,\n textContent: label,\n attributes: {\n type: 'button',\n 'aria-label': label,\n },\n })\n\n if (disabled) {\n button.setAttribute('disabled', 'disabled')\n button.setAttribute('aria-disabled', 'true')\n }\n\n return button\n }\n\n /**\n * ページ番号ボタンを作成\n */\n private createPageButton(page: number, isActive: boolean): HTMLElement {\n const button = createElement('button', {\n className: `pagination-button pagination-page-button ${isActive ? 'active' : ''}`,\n textContent: String(page),\n attributes: {\n type: 'button',\n 'aria-label': `ページ ${page}`,\n 'aria-current': isActive ? 'page' : 'false',\n },\n })\n\n if (isActive) {\n button.setAttribute('data-active', '')\n }\n\n return button\n }\n\n /**\n * 表示件数をレンダリング\n */\n private renderItemCount(): HTMLElement {\n const { start, end } = this.getItemRange()\n const { totalItems } = this.state\n\n const container = createElement('div', { className: 'pagination-item-count' })\n\n const text = totalItems > 0\n ? `${totalItems}件中 ${start}-${end}件を表示`\n : '0件'\n\n const span = createElement('span', {\n className: 'item-count-text',\n textContent: text,\n attributes: {\n 'aria-live': 'polite',\n 'aria-atomic': 'true',\n },\n })\n\n container.appendChild(span)\n\n return container\n }\n\n // ===========================================================================\n // Static Field Renderer\n // ===========================================================================\n\n /**\n * PaginationフィールドをHTMLとしてレンダリング(静的メソッド)\n * SSR/初期レンダリング用\n */\n static renderField(field: InputField): string {\n const paginationField = field as InputField & {\n totalItems?: number\n pageSize?: number\n currentPage?: number\n }\n const totalItems = paginationField.totalItems ?? 0\n const pageSize = paginationField.pageSize ?? 10\n const currentPage = paginationField.currentPage ?? 1\n const totalPages = Math.ceil(totalItems / pageSize)\n\n const startItem = totalItems > 0 ? (currentPage - 1) * pageSize + 1 : 0\n const endItem = Math.min(currentPage * pageSize, totalItems)\n\n const paginationHtml = `\n <div class=\"mokkun-pagination pagination-align-center\">\n <div class=\"pagination-wrapper\">\n <div class=\"pagination-page-size-selector\">\n <label class=\"page-size-label\">表示件数:</label>\n <select class=\"page-size-select\" aria-label=\"ページサイズ選択\">\n <option value=\"10\" ${pageSize === 10 ? 'selected' : ''}>10件</option>\n <option value=\"25\" ${pageSize === 25 ? 'selected' : ''}>25件</option>\n <option value=\"50\" ${pageSize === 50 ? 'selected' : ''}>50件</option>\n <option value=\"100\" ${pageSize === 100 ? 'selected' : ''}>100件</option>\n </select>\n </div>\n <div class=\"pagination-navigation\">\n <button type=\"button\" class=\"pagination-button pagination-button-first\" ${currentPage === 1 ? 'disabled' : ''} aria-label=\"最初\">最初</button>\n <button type=\"button\" class=\"pagination-button pagination-button-prev\" ${currentPage === 1 ? 'disabled' : ''} aria-label=\"前へ\">前へ</button>\n ${Array.from({ length: Math.min(totalPages, 7) }, (_, i) => {\n const page = i + 1\n return `<button type=\"button\" class=\"pagination-button pagination-page-button ${page === currentPage ? 'active' : ''}\" aria-label=\"ページ ${page}\" ${page === currentPage ? 'aria-current=\"page\"' : ''}>${page}</button>`\n }).join('')}\n <button type=\"button\" class=\"pagination-button pagination-button-next\" ${currentPage === totalPages || totalPages === 0 ? 'disabled' : ''} aria-label=\"次へ\">次へ</button>\n <button type=\"button\" class=\"pagination-button pagination-button-last\" ${currentPage === totalPages || totalPages === 0 ? 'disabled' : ''} aria-label=\"最後\">最後</button>\n </div>\n <div class=\"pagination-item-count\">\n <span class=\"item-count-text\" aria-live=\"polite\">${totalItems > 0 ? `${totalItems}件中 ${startItem}-${endItem}件を表示` : '0件'}</span>\n </div>\n </div>\n </div>\n `\n\n return createFieldWrapper(field, paginationHtml)\n }\n}\n\n// =============================================================================\n// Factory Function\n// =============================================================================\n\n/**\n * Paginationを作成するファクトリ関数\n */\nexport function createPagination(\n container: HTMLElement,\n config: PaginationConfig,\n callbacks: PaginationCallbacks = {}\n): Pagination {\n const pagination = new Pagination(container, config, callbacks)\n pagination.render()\n return pagination\n}\n","/**\n * Toggle Component\n * トグルスイッチコンポーネント\n *\n * API follows standard conventions from Headless UI and Radix UI:\n * - `checked` / `defaultChecked` for state\n * - `data-state=\"checked|unchecked\"` for styling\n * - `data-disabled` when disabled\n * - `role=\"switch\"` with `aria-checked` for accessibility\n * - `onCheckedChange` callback (Radix UI compatible)\n */\n\nimport { createElement, generateId } from '../utils/dom'\nimport { escapeHtml, createFieldWrapper } from '../utils/field-helpers'\nimport type { InputField } from '../../types/schema'\n\n// =============================================================================\n// Types\n// =============================================================================\n\n/**\n * トグルの状態\n */\nexport interface ToggleState {\n /** チェック状態 */\n checked: boolean\n /** 無効化状態 */\n disabled: boolean\n}\n\n/**\n * トグルのコールバック\n */\nexport interface ToggleCallbacks {\n /** 状態変更時 */\n onChange?: (checked: boolean, state: ToggleState) => void\n /** Radix UI互換: 状態変更時 */\n onCheckedChange?: (checked: boolean) => void\n}\n\n/**\n * トグルの設定\n */\nexport interface ToggleConfig {\n /** 初期チェック状態 */\n defaultChecked?: boolean\n /** 無効化 */\n disabled?: boolean\n /** チェック時ラベル */\n checkedLabel?: string\n /** 非チェック時ラベル */\n uncheckedLabel?: string\n /** サイズ ( small/medium) */\n size?: 'small' | 'medium' | 'large'\n /** name属性(フォーム用) */\n name?: string\n /** ラベル位置 () */\n labelPosition?: 'left' | 'right'\n}\n\n// =============================================================================\n// Toggle Class\n// =============================================================================\n\n/**\n * トグルコンポーネント\n */\nexport class Toggle {\n private config: ToggleConfig\n private state: ToggleState\n private callbacks: ToggleCallbacks\n private container: HTMLElement\n private instanceId: string\n\n constructor(\n container: HTMLElement,\n config: ToggleConfig = {},\n callbacks: ToggleCallbacks = {}\n ) {\n this.config = config\n this.container = container\n this.callbacks = callbacks\n this.instanceId = generateId('toggle')\n this.state = this.createInitialState()\n }\n\n // ===========================================================================\n // Public Methods\n // ===========================================================================\n\n /**\n * トグルをレンダリング\n */\n render(): void {\n this.container.innerHTML = ''\n\n const size = this.config.size ?? 'medium'\n const labelPosition = this.config.labelPosition ?? 'right'\n this.container.className = `mokkun-toggle toggle-${size} toggle-label-${labelPosition}`\n\n // data-state属性を設定(Radix UI / Headless UI互換)\n this.container.setAttribute('data-state', this.state.checked ? 'checked' : 'unchecked')\n if (this.state.disabled) {\n this.container.setAttribute('data-disabled', '')\n } else {\n this.container.removeAttribute('data-disabled')\n }\n\n const wrapper = createElement('div', { className: 'toggle-wrapper' })\n\n // ラベル(左側に配置する場合)\n if (labelPosition === 'left') {\n const label = this.renderLabel()\n wrapper.appendChild(label)\n }\n\n // トグルスイッチ\n const toggle = this.renderToggle()\n wrapper.appendChild(toggle)\n\n // ラベル(右側に配置する場合)\n if (labelPosition === 'right') {\n const label = this.renderLabel()\n wrapper.appendChild(label)\n }\n\n this.container.appendChild(wrapper)\n }\n\n /**\n * チェック状態を設定\n */\n setChecked(checked: boolean): void {\n if (this.state.disabled) {\n return\n }\n\n if (this.state.checked === checked) {\n return\n }\n\n this.state = {\n ...this.state,\n checked,\n }\n\n this.render()\n this.callbacks.onChange?.(checked, this.state)\n this.callbacks.onCheckedChange?.(checked)\n }\n\n /**\n * 状態をトグル\n */\n toggle(): void {\n this.setChecked(!this.state.checked)\n }\n\n /**\n * 無効化状態を設定\n */\n setDisabled(disabled: boolean): void {\n if (this.state.disabled === disabled) {\n return\n }\n\n this.state = {\n ...this.state,\n disabled,\n }\n\n this.render()\n }\n\n /**\n * 現在の状態を取得\n */\n getState(): ToggleState {\n return { ...this.state }\n }\n\n /**\n * チェック状態を取得\n */\n isChecked(): boolean {\n return this.state.checked\n }\n\n /**\n * 無効化されているかどうかを取得\n */\n isDisabled(): boolean {\n return this.state.disabled\n }\n\n // ===========================================================================\n // Private Methods\n // ===========================================================================\n\n /**\n * 初期状態を作成\n */\n private createInitialState(): ToggleState {\n return {\n checked: this.config.defaultChecked ?? false,\n disabled: this.config.disabled ?? false,\n }\n }\n\n /**\n * トグルスイッチをレンダリング\n */\n private renderToggle(): HTMLElement {\n const toggleContainer = createElement('div', {\n className: 'toggle-switch-container',\n })\n\n // 非表示のチェックボックス(アクセシビリティ用)\n const checkbox = createElement('input', {\n className: 'toggle-checkbox visually-hidden',\n attributes: {\n type: 'checkbox',\n id: this.instanceId,\n role: 'switch',\n 'aria-checked': String(this.state.checked),\n 'aria-label': this.state.checked\n ? (this.config.checkedLabel ?? 'ON')\n : (this.config.uncheckedLabel ?? 'OFF'),\n },\n })\n\n if (this.config.name) {\n checkbox.setAttribute('name', this.config.name)\n }\n\n if (this.state.checked) {\n checkbox.setAttribute('checked', 'checked')\n }\n\n if (this.state.disabled) {\n checkbox.setAttribute('disabled', 'disabled')\n checkbox.setAttribute('aria-disabled', 'true')\n }\n\n // 変更イベント\n checkbox.addEventListener('change', (e) => {\n const target = e.target as HTMLInputElement\n this.setChecked(target.checked)\n })\n\n // キーボードイベント(Spaceキー対応)\n checkbox.addEventListener('keydown', (e) => {\n if (e.key === ' ' || e.key === 'Enter') {\n e.preventDefault()\n if (!this.state.disabled) {\n this.toggle()\n }\n }\n })\n\n toggleContainer.appendChild(checkbox)\n\n // 視覚的なトグルスイッチ\n const stateClass = this.state.checked ? 'checked' : 'unchecked'\n const classNames = [\n 'toggle-switch',\n stateClass,\n this.state.disabled ? 'disabled' : '',\n ].filter(Boolean).join(' ')\n\n const toggleSwitch = createElement('label', {\n className: classNames,\n attributes: {\n for: this.instanceId,\n 'data-state': stateClass,\n },\n })\n\n if (this.state.disabled) {\n toggleSwitch.setAttribute('data-disabled', '')\n }\n\n // トラック\n const track = createElement('span', { className: 'toggle-track' })\n toggleSwitch.appendChild(track)\n\n // Thumb(標準的な命名)\n const thumb = createElement('span', {\n className: 'toggle-thumb',\n attributes: {\n 'data-state': stateClass,\n },\n })\n toggleSwitch.appendChild(thumb)\n\n toggleContainer.appendChild(toggleSwitch)\n\n return toggleContainer\n }\n\n /**\n * ラベルをレンダリング\n */\n private renderLabel(): HTMLElement {\n const checkedLabel = this.config.checkedLabel ?? 'ON'\n const uncheckedLabel = this.config.uncheckedLabel ?? 'OFF'\n\n const stateClass = this.state.checked ? 'checked' : 'unchecked'\n const classNames = [\n 'toggle-label',\n stateClass,\n this.state.disabled ? 'disabled' : '',\n ].filter(Boolean).join(' ')\n\n const label = createElement('span', {\n className: classNames,\n textContent: this.state.checked ? checkedLabel : uncheckedLabel,\n attributes: {\n 'aria-live': 'polite',\n 'data-state': stateClass,\n },\n })\n\n if (this.state.disabled) {\n label.setAttribute('data-disabled', '')\n }\n\n return label\n }\n\n // ===========================================================================\n // Static Field Renderer\n // ===========================================================================\n\n /**\n * ToggleフィールドをHTMLとしてレンダリング(静的メソッド)\n * SSR/初期レンダリング用\n */\n static renderField(field: InputField): string {\n const toggleField = field as InputField & {\n defaultChecked?: boolean\n checkedLabel?: string\n uncheckedLabel?: string\n size?: 'small' | 'medium' | 'large'\n }\n const checked = toggleField.defaultChecked ?? false\n const checkedLabel = toggleField.checkedLabel ?? 'ON'\n const uncheckedLabel = toggleField.uncheckedLabel ?? 'OFF'\n const size = toggleField.size ?? 'medium'\n const stateClass = checked ? 'checked' : 'unchecked'\n\n const toggleHtml = `\n <div class=\"mokkun-toggle toggle-${size} toggle-label-right\" data-state=\"${stateClass}\">\n <div class=\"toggle-wrapper\">\n <div class=\"toggle-switch-container\">\n <input type=\"checkbox\" class=\"toggle-checkbox visually-hidden\" id=\"${escapeHtml(field.id)}\" role=\"switch\" aria-checked=\"${checked}\" ${checked ? 'checked' : ''}>\n <label class=\"toggle-switch ${stateClass}\" for=\"${escapeHtml(field.id)}\" data-state=\"${stateClass}\">\n <span class=\"toggle-track\"></span>\n <span class=\"toggle-thumb\" data-state=\"${stateClass}\"></span>\n </label>\n </div>\n <span class=\"toggle-label ${stateClass}\" aria-live=\"polite\" data-state=\"${stateClass}\">${escapeHtml(checked ? checkedLabel : uncheckedLabel)}</span>\n </div>\n </div>\n `\n\n return createFieldWrapper(field, toggleHtml)\n }\n}\n\n// =============================================================================\n// Factory Function\n// =============================================================================\n\n/**\n * Toggleを作成するファクトリ関数\n */\nexport function createToggle(\n container: HTMLElement,\n config: ToggleConfig = {},\n callbacks: ToggleCallbacks = {}\n): Toggle {\n const toggle = new Toggle(container, config, callbacks)\n toggle.render()\n return toggle\n}\n","/**\n * Badge Component\n * バッジコンポーネント\n *\n * \n * - カラーバリエーション(gray/blue/green/yellow/red)\n * - サイズ(small/medium)\n * - dot表示(数値なしの状態表示)\n * - カウント表示(99+などの上限表示)\n * - `data-color` / `data-size` for styling\n * - `role=\"status\"` with `aria-label` for accessibility\n */\n\nimport { createElement } from '../utils/dom'\nimport { escapeHtml, createFieldWrapper } from '../utils/field-helpers'\nimport type { InputField } from '../../types/schema'\n\n// =============================================================================\n// Types\n// =============================================================================\n\n/**\n * バッジの状態\n */\nexport interface BadgeState {\n /** 表示する数値 */\n count: number | null\n /** 表示するテキスト */\n text: string | null\n /** dotモード */\n dot: boolean\n /** 非表示状態 */\n hidden: boolean\n}\n\n/**\n * バッジのコールバック\n */\nexport interface BadgeCallbacks {\n /** カウント変更時 */\n onCountChange?: (count: number | null) => void\n /** クリック時 */\n onClick?: (event: MouseEvent) => void\n}\n\n/**\n * バッジの設定\n */\nexport interface BadgeConfig {\n /** カラー */\n color?: 'gray' | 'blue' | 'green' | 'yellow' | 'red'\n /** サイズ */\n size?: 'small' | 'medium'\n /** dotモード(数値なしの状態表示) */\n dot?: boolean\n /** 初期カウント */\n count?: number\n /** カウント表示の上限(デフォルト: 99) */\n maxCount?: number\n /** テキストコンテンツ(数値の代わりにテキストを表示) */\n text?: string\n /** ラベル(アクセシビリティ用) */\n label?: string\n /** クリック可能か */\n clickable?: boolean\n /** 0の時に非表示にするか */\n hideOnZero?: boolean\n}\n\n// =============================================================================\n// Badge Class\n// =============================================================================\n\n/**\n * バッジコンポーネント\n */\nexport class Badge {\n private config: BadgeConfig\n private state: BadgeState\n private callbacks: BadgeCallbacks\n private container: HTMLElement\n private clickHandler: ((event: MouseEvent) => void) | null = null\n\n constructor(\n container: HTMLElement,\n config: BadgeConfig = {},\n callbacks: BadgeCallbacks = {}\n ) {\n this.config = config\n this.container = container\n this.callbacks = callbacks\n this.state = this.createInitialState()\n }\n\n // ===========================================================================\n // Public Methods\n // ===========================================================================\n\n /**\n * バッジをレンダリング\n */\n render(): void {\n this.container.innerHTML = ''\n\n const color = this.config.color ?? 'gray'\n const size = this.config.size ?? 'medium'\n const clickable = this.config.clickable ?? false\n\n this.container.className = `mokkun-badge badge-${color} badge-${size}`\n\n if (clickable) {\n this.container.classList.add('badge-clickable')\n }\n\n if (this.state.dot) {\n this.container.classList.add('badge-dot')\n }\n\n // data属性を設定\n this.container.setAttribute('data-color', color)\n this.container.setAttribute('data-size', size)\n\n if (this.state.hidden) {\n this.container.setAttribute('data-hidden', '')\n this.container.style.display = 'none'\n return\n } else {\n this.container.removeAttribute('data-hidden')\n this.container.style.display = ''\n }\n\n // バッジ要素を作成\n const badge = this.renderBadge()\n this.container.appendChild(badge)\n\n // クリックイベント\n // 既存のイベントリスナーを削除\n if (this.clickHandler) {\n this.container.removeEventListener('click', this.clickHandler)\n this.clickHandler = null\n }\n\n if (clickable && this.callbacks.onClick) {\n this.clickHandler = this.handleClick.bind(this)\n this.container.addEventListener('click', this.clickHandler)\n }\n }\n\n /**\n * カウントを設定\n */\n setCount(count: number): void {\n if (count < 0) {\n count = 0\n }\n\n if (this.state.count === count) {\n return\n }\n\n this.state = {\n ...this.state,\n count,\n text: null, // カウントを設定するとテキストはクリア\n hidden: (this.config.hideOnZero === true) && count === 0,\n }\n\n this.render()\n this.callbacks.onCountChange?.(count)\n }\n\n /**\n * テキストを設定\n */\n setText(text: string): void {\n if (this.state.text === text) {\n return\n }\n\n this.state = {\n ...this.state,\n text,\n count: null, // テキストを設定するとカウントはクリア\n hidden: false,\n }\n\n this.render()\n }\n\n /**\n * dotモードを設定\n */\n setDot(dot: boolean): void {\n if (this.state.dot === dot) {\n return\n }\n\n this.state = {\n ...this.state,\n dot,\n }\n\n this.render()\n }\n\n /**\n * 非表示状態を設定\n */\n setHidden(hidden: boolean): void {\n if (this.state.hidden === hidden) {\n return\n }\n\n this.state = {\n ...this.state,\n hidden,\n }\n\n this.render()\n }\n\n /**\n * 現在のカウントを取得\n */\n getCount(): number | null {\n return this.state.count\n }\n\n /**\n * 現在のテキストを取得\n */\n getText(): string | null {\n return this.state.text\n }\n\n /**\n * 現在の状態を取得\n */\n getState(): Readonly<BadgeState> {\n return { ...this.state }\n }\n\n /**\n * コンポーネントを破棄\n */\n destroy(): void {\n if (this.clickHandler) {\n this.container.removeEventListener('click', this.clickHandler)\n this.clickHandler = null\n }\n this.container.innerHTML = ''\n }\n\n // ===========================================================================\n // Private Methods\n // ===========================================================================\n\n /**\n * 初期状態を作成\n */\n private createInitialState(): BadgeState {\n const count = this.config.count ?? null\n const text = this.config.text ?? null\n const dot = this.config.dot ?? false\n const hideOnZero = this.config.hideOnZero === true\n\n return {\n count,\n text,\n dot,\n hidden: hideOnZero && count === 0,\n }\n }\n\n /**\n * バッジ要素をレンダリング\n */\n private renderBadge(): HTMLElement {\n const badge = createElement('span', {\n className: 'badge-content',\n })\n\n // ARIA属性\n badge.setAttribute('role', 'status')\n\n // アクセシビリティ用のラベル\n const ariaLabel = this.getAriaLabel()\n if (ariaLabel) {\n badge.setAttribute('aria-label', ariaLabel)\n }\n\n // dotモードの場合\n if (this.state.dot) {\n const dot = createElement('span', {\n className: 'badge-dot-indicator',\n attributes: {\n 'aria-hidden': 'true',\n },\n })\n badge.appendChild(dot)\n return badge\n }\n\n // テキスト表示\n if (this.state.text !== null) {\n badge.textContent = this.state.text\n return badge\n }\n\n // カウント表示\n if (this.state.count !== null) {\n const displayCount = this.formatCount(this.state.count)\n badge.textContent = displayCount\n return badge\n }\n\n // フォールバック(空のバッジ)\n return badge\n }\n\n /**\n * カウントをフォーマット\n */\n private formatCount(count: number): string {\n const maxCount = this.config.maxCount ?? 99\n\n if (count > maxCount) {\n return `${maxCount}+`\n }\n\n return String(count)\n }\n\n /**\n * アクセシビリティ用のラベルを取得\n */\n private getAriaLabel(): string {\n // config.labelが指定されている場合はそれを使用\n if (this.config.label) {\n return this.config.label\n }\n\n // dotモードの場合\n if (this.state.dot) {\n return 'Status indicator'\n }\n\n // テキスト表示の場合\n if (this.state.text !== null) {\n return this.state.text\n }\n\n // カウント表示の場合\n if (this.state.count !== null) {\n const count = this.state.count\n const maxCount = this.config.maxCount ?? 99\n\n if (count > maxCount) {\n return `${maxCount}+ notifications`\n }\n\n return `${count} notification${count === 1 ? '' : 's'}`\n }\n\n return ''\n }\n\n /**\n * クリックイベントハンドラー\n */\n private handleClick(event: MouseEvent): void {\n this.callbacks.onClick?.(event)\n }\n\n // ===========================================================================\n // Static Field Renderer\n // ===========================================================================\n\n /**\n * BadgeフィールドをHTMLとしてレンダリング(静的メソッド)\n * SSR/初期レンダリング用\n */\n static renderField(field: InputField): string {\n const badgeField = field as InputField & {\n text?: string\n variant?: 'default' | 'primary' | 'success' | 'warning' | 'danger' | 'info'\n }\n const text = badgeField.text ?? field.label\n const variant = badgeField.variant ?? 'default'\n\n const badgeHtml = `\n <span class=\"mokkun-badge badge-${variant}\">${escapeHtml(text)}</span>\n `\n\n return createFieldWrapper(field, badgeHtml)\n }\n}\n\n// =============================================================================\n// Factory Function\n// =============================================================================\n\n/**\n * バッジを作成\n */\nexport function createBadge(\n container: HTMLElement,\n config: BadgeConfig = {},\n callbacks: BadgeCallbacks = {}\n): Badge {\n const badge = new Badge(container, config, callbacks)\n badge.render()\n return badge\n}\n","/**\n * Browser Component\n * 階層構造を持つデータの中から項目を単一選択するコンポーネント\n *\n * https://smarthr.design/products/components/browser/\n *\n * 機能:\n * - 階層的なデータの表示\n * - 複数カラム表示(最大3列)\n * - キーボードナビゲーション\n * - 単一選択\n * - アクセシビリティ対応(ARIA属性)\n *\n * 用途:\n * - カテゴリ選択\n * - ファイルブラウジング\n * - 組織階層の選択\n */\n\nimport { createElement, generateId } from '../utils/dom'\nimport { createFieldWrapper } from '../utils/field-helpers'\nimport type { InputField } from '../../types/schema'\n\n// =============================================================================\n// Types\n// =============================================================================\n\n/**\n * Browserアイテムの定義\n */\nexport interface BrowserItem {\n /** アイテムの値(一意) */\n value: string\n /** 表示ラベル */\n label: string\n /** 子アイテム */\n children?: BrowserItem[]\n /** 無効化 */\n disabled?: boolean\n}\n\n/**\n * Browserの状態\n */\nexport interface BrowserState {\n /** 選択中のアイテムのvalue */\n selectedValue: string | null\n /** 選択パス(ルートからのvalue配列) */\n selectedPath: string[]\n /** フォーカス中のカラムインデックス */\n focusedColumnIndex: number\n /** 各カラムでフォーカス中のアイテムのインデックス */\n focusedItemIndexes: number[]\n}\n\n/**\n * Browserのコールバック\n */\nexport interface BrowserCallbacks {\n /** アイテム選択時 */\n onSelect?: (value: string, path: string[], item: BrowserItem) => void\n /** 選択変更時 */\n onChange?: (value: string | null, path: string[]) => void\n}\n\n/**\n * Browserの設定\n */\nexport interface BrowserConfig {\n /** アイテムの配列 */\n items: BrowserItem[]\n /** 初期選択値 */\n defaultValue?: string\n /** ID属性 */\n id?: string\n /** カスタムCSSクラス */\n className?: string\n /** 最大カラム数(デフォルト: 3) */\n maxColumns?: number\n /** 高さ(デフォルト: 'auto') */\n height?: string\n}\n\n/**\n * 内部用: カラムデータ\n */\ninterface ColumnData {\n items: BrowserItem[]\n parentValue: string | null\n}\n\n// =============================================================================\n// Browser Class\n// =============================================================================\n\n/**\n * Browserコンポーネント\n */\nexport class Browser {\n private config: BrowserConfig\n private state: BrowserState\n private callbacks: BrowserCallbacks\n private container: HTMLElement\n private instanceId: string\n private columnsWrapper: HTMLElement | null = null\n private itemsMap: Map<string, BrowserItem> = new Map()\n private parentMap: Map<string, string | null> = new Map()\n\n constructor(\n container: HTMLElement,\n config: BrowserConfig,\n callbacks: BrowserCallbacks = {}\n ) {\n this.config = config\n this.container = container\n this.callbacks = callbacks\n this.instanceId = config.id ?? generateId('browser')\n\n // アイテムマップを構築\n this.buildItemsMap(config.items, null)\n\n // 初期状態\n const initialPath = config.defaultValue\n ? this.getPathToValue(config.defaultValue)\n : []\n\n this.state = {\n selectedValue: config.defaultValue ?? null,\n selectedPath: initialPath,\n focusedColumnIndex: 0,\n focusedItemIndexes: new Array(config.maxColumns ?? 3).fill(0),\n }\n }\n\n // ===========================================================================\n // Public Methods\n // ===========================================================================\n\n /**\n * Browserをレンダリング\n */\n render(): void {\n this.container.innerHTML = ''\n\n this.container.className = [\n 'mokkun-browser',\n this.config.className ?? '',\n ]\n .filter(Boolean)\n .join(' ')\n\n this.container.id = this.instanceId\n this.container.setAttribute('role', 'application')\n this.container.setAttribute('aria-label', '階層ブラウザ')\n\n if (this.config.height && this.config.height !== 'auto') {\n this.container.style.height = this.config.height\n }\n\n // カラムラッパー\n this.columnsWrapper = createElement('div', {\n className: 'browser-columns',\n })\n\n // キーボードイベント\n this.container.addEventListener('keydown', this.handleKeyDown.bind(this))\n\n this.container.appendChild(this.columnsWrapper)\n this.renderColumns()\n }\n\n /**\n * 値を選択\n */\n selectValue(value: string): void {\n const item = this.itemsMap.get(value)\n if (!item || item.disabled) return\n\n const path = this.getPathToValue(value)\n this.state = {\n ...this.state,\n selectedValue: value,\n selectedPath: path,\n }\n\n this.renderColumns()\n this.callbacks.onSelect?.(value, path, item)\n this.callbacks.onChange?.(value, path)\n }\n\n /**\n * 選択をクリア\n */\n clearSelection(): void {\n this.state = {\n ...this.state,\n selectedValue: null,\n selectedPath: [],\n }\n\n this.renderColumns()\n this.callbacks.onChange?.(null, [])\n }\n\n /**\n * 現在の選択値を取得\n */\n getValue(): string | null {\n return this.state.selectedValue\n }\n\n /**\n * 現在の選択パスを取得\n */\n getPath(): string[] {\n return [...this.state.selectedPath]\n }\n\n /**\n * 現在の状態を取得\n */\n getState(): BrowserState {\n return { ...this.state }\n }\n\n /**\n * アイテムを更新\n */\n setItems(items: BrowserItem[]): void {\n this.config = { ...this.config, items }\n this.itemsMap.clear()\n this.parentMap.clear()\n this.buildItemsMap(items, null)\n\n // 選択値が新しいアイテムに存在しなければクリア\n if (this.state.selectedValue && !this.itemsMap.has(this.state.selectedValue)) {\n this.state = {\n ...this.state,\n selectedValue: null,\n selectedPath: [],\n }\n }\n\n this.renderColumns()\n }\n\n /**\n * コンポーネントを破棄\n */\n destroy(): void {\n this.container.innerHTML = ''\n this.columnsWrapper = null\n this.itemsMap.clear()\n this.parentMap.clear()\n }\n\n // ===========================================================================\n // Private Methods - Data\n // ===========================================================================\n\n private buildItemsMap(items: BrowserItem[], parentValue: string | null): void {\n for (const item of items) {\n this.itemsMap.set(item.value, item)\n this.parentMap.set(item.value, parentValue)\n\n if (item.children && item.children.length > 0) {\n this.buildItemsMap(item.children, item.value)\n }\n }\n }\n\n private getPathToValue(value: string): string[] {\n const path: string[] = []\n let currentValue: string | null = value\n\n while (currentValue !== null) {\n path.unshift(currentValue)\n currentValue = this.parentMap.get(currentValue) ?? null\n }\n\n return path\n }\n\n private getColumnsData(): ColumnData[] {\n const columns: ColumnData[] = []\n const maxColumns = this.config.maxColumns ?? 3\n\n // 最初のカラムはルートアイテム\n columns.push({\n items: this.config.items,\n parentValue: null,\n })\n\n // 選択パスに基づいて追加カラムを生成\n for (let i = 0; i < this.state.selectedPath.length && columns.length < maxColumns; i++) {\n const selectedValue = this.state.selectedPath[i]\n const item = this.itemsMap.get(selectedValue)\n\n if (item?.children && item.children.length > 0) {\n columns.push({\n items: item.children,\n parentValue: selectedValue,\n })\n }\n }\n\n return columns\n }\n\n // ===========================================================================\n // Private Methods - Rendering\n // ===========================================================================\n\n private renderColumns(): void {\n if (!this.columnsWrapper) return\n\n this.columnsWrapper.innerHTML = ''\n const columnsData = this.getColumnsData()\n\n columnsData.forEach((columnData, columnIndex) => {\n const column = this.renderColumn(columnData, columnIndex)\n this.columnsWrapper!.appendChild(column)\n })\n }\n\n private renderColumn(columnData: ColumnData, columnIndex: number): HTMLElement {\n const column = createElement('div', {\n className: 'browser-column',\n attributes: {\n role: 'listbox',\n 'aria-label': `カラム ${columnIndex + 1}`,\n 'data-column-index': String(columnIndex),\n },\n })\n\n columnData.items.forEach((item, itemIndex) => {\n const itemElement = this.renderItem(item, columnIndex, itemIndex)\n column.appendChild(itemElement)\n })\n\n return column\n }\n\n private renderItem(item: BrowserItem, columnIndex: number, itemIndex: number): HTMLElement {\n const isSelected = this.state.selectedPath.includes(item.value)\n const isLeafSelected = this.state.selectedValue === item.value\n const hasChildren = item.children && item.children.length > 0\n const isFocused = this.state.focusedColumnIndex === columnIndex &&\n this.state.focusedItemIndexes[columnIndex] === itemIndex\n\n const itemWrapper = createElement('label', {\n className: [\n 'browser-item',\n isSelected ? 'is-selected' : '',\n isLeafSelected ? 'is-leaf-selected' : '',\n item.disabled ? 'is-disabled' : '',\n isFocused ? 'is-focused' : '',\n ].filter(Boolean).join(' '),\n attributes: {\n 'data-value': item.value,\n 'data-column': String(columnIndex),\n 'data-index': String(itemIndex),\n },\n })\n\n // ラジオボタン(非表示)\n const radio = document.createElement('input')\n radio.type = 'radio'\n radio.name = `${this.instanceId}-column-${columnIndex}`\n radio.value = item.value\n radio.checked = isSelected\n radio.disabled = item.disabled ?? false\n radio.tabIndex = isFocused ? 0 : -1\n radio.className = 'browser-item-radio'\n radio.setAttribute('aria-label', item.label)\n\n radio.addEventListener('change', () => {\n if (!item.disabled) {\n this.handleItemSelect(item, columnIndex, itemIndex)\n }\n })\n\n radio.addEventListener('focus', () => {\n this.state = {\n ...this.state,\n focusedColumnIndex: columnIndex,\n focusedItemIndexes: this.state.focusedItemIndexes.map((idx, i) =>\n i === columnIndex ? itemIndex : idx\n ),\n }\n })\n\n itemWrapper.appendChild(radio)\n\n // ラベルコンテナ\n const labelContainer = createElement('span', {\n className: 'browser-item-content',\n })\n\n // ラベルテキスト\n const labelText = createElement('span', {\n className: 'browser-item-label',\n textContent: item.label,\n })\n labelContainer.appendChild(labelText)\n\n // 子要素がある場合は矢印アイコン\n if (hasChildren) {\n const arrow = this.renderArrowIcon()\n labelContainer.appendChild(arrow)\n }\n\n itemWrapper.appendChild(labelContainer)\n\n // クリックイベント\n itemWrapper.addEventListener('click', (e) => {\n if (item.disabled) {\n e.preventDefault()\n return\n }\n this.handleItemSelect(item, columnIndex, itemIndex)\n })\n\n return itemWrapper\n }\n\n private renderArrowIcon(): HTMLElement {\n const icon = createElement('span', {\n className: 'browser-item-arrow',\n attributes: {\n 'aria-hidden': 'true',\n },\n })\n\n const svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg')\n svg.setAttribute('width', '16')\n svg.setAttribute('height', '16')\n svg.setAttribute('viewBox', '0 0 16 16')\n svg.setAttribute('fill', 'currentColor')\n\n const path = document.createElementNS('http://www.w3.org/2000/svg', 'path')\n path.setAttribute('d', 'M6 3l5 5-5 5V3z')\n\n svg.appendChild(path)\n icon.appendChild(svg)\n\n return icon\n }\n\n // ===========================================================================\n // Private Methods - Event Handlers\n // ===========================================================================\n\n private handleItemSelect(item: BrowserItem, columnIndex: number, itemIndex: number): void {\n // パスを更新\n const newPath = [...this.state.selectedPath.slice(0, columnIndex), item.value]\n\n // 子がない場合は最終選択\n const hasChildren = item.children && item.children.length > 0\n\n this.state = {\n ...this.state,\n selectedValue: item.value,\n selectedPath: newPath,\n focusedColumnIndex: hasChildren ? columnIndex + 1 : columnIndex,\n focusedItemIndexes: this.state.focusedItemIndexes.map((idx, i) => {\n if (i === columnIndex) return itemIndex\n if (i === columnIndex + 1) return 0\n return idx\n }),\n }\n\n this.renderColumns()\n this.callbacks.onSelect?.(item.value, newPath, item)\n this.callbacks.onChange?.(item.value, newPath)\n\n // 子がある場合、次のカラムの最初のアイテムにフォーカス\n if (hasChildren) {\n setTimeout(() => {\n this.focusCurrentItem()\n }, 0)\n }\n }\n\n private handleKeyDown(event: KeyboardEvent): void {\n const columnsData = this.getColumnsData()\n const currentColumn = columnsData[this.state.focusedColumnIndex]\n if (!currentColumn) return\n\n switch (event.key) {\n case 'ArrowUp':\n event.preventDefault()\n this.moveFocus(-1, 0)\n break\n\n case 'ArrowDown':\n event.preventDefault()\n this.moveFocus(1, 0)\n break\n\n case 'ArrowLeft':\n event.preventDefault()\n this.moveFocus(0, -1)\n break\n\n case 'ArrowRight':\n case 'Enter':\n case ' ':\n event.preventDefault()\n this.selectFocusedOrMoveRight()\n break\n }\n }\n\n private moveFocus(rowDelta: number, colDelta: number): void {\n const columnsData = this.getColumnsData()\n let newColumnIndex = this.state.focusedColumnIndex + colDelta\n newColumnIndex = Math.max(0, Math.min(newColumnIndex, columnsData.length - 1))\n\n const column = columnsData[newColumnIndex]\n if (!column) return\n\n let newItemIndex = this.state.focusedItemIndexes[newColumnIndex] + rowDelta\n newItemIndex = Math.max(0, Math.min(newItemIndex, column.items.length - 1))\n\n this.state = {\n ...this.state,\n focusedColumnIndex: newColumnIndex,\n focusedItemIndexes: this.state.focusedItemIndexes.map((idx, i) =>\n i === newColumnIndex ? newItemIndex : idx\n ),\n }\n\n this.renderColumns()\n this.focusCurrentItem()\n }\n\n private selectFocusedOrMoveRight(): void {\n const columnsData = this.getColumnsData()\n const currentColumn = columnsData[this.state.focusedColumnIndex]\n if (!currentColumn) return\n\n const itemIndex = this.state.focusedItemIndexes[this.state.focusedColumnIndex]\n const item = currentColumn.items[itemIndex]\n if (!item || item.disabled) return\n\n this.handleItemSelect(item, this.state.focusedColumnIndex, itemIndex)\n }\n\n private focusCurrentItem(): void {\n const selector = `.browser-item[data-column=\"${this.state.focusedColumnIndex}\"][data-index=\"${this.state.focusedItemIndexes[this.state.focusedColumnIndex]}\"] .browser-item-radio`\n const input = this.container.querySelector<HTMLInputElement>(selector)\n input?.focus()\n }\n\n // ===========================================================================\n // Static Field Renderer\n // ===========================================================================\n\n static renderField(field: InputField): string {\n const browserHtml = `\n <div class=\"mokkun-browser browser-placeholder\">\n <div class=\"browser-toolbar\">\n <div class=\"browser-controls\">\n <span class=\"browser-dot browser-dot-red\"></span>\n <span class=\"browser-dot browser-dot-yellow\"></span>\n <span class=\"browser-dot browser-dot-green\"></span>\n </div>\n <div class=\"browser-url-bar\">\n <span class=\"browser-url\">https://example.com</span>\n </div>\n </div>\n <div class=\"browser-content\">\n <p class=\"browser-placeholder-text\">ブラウザコンテンツ</p>\n </div>\n </div>\n `\n return createFieldWrapper(field, browserHtml)\n }\n}\n\n// =============================================================================\n// Factory Function\n// =============================================================================\n\n/**\n * Browserを作成\n */\nexport function createBrowser(\n container: HTMLElement,\n config: BrowserConfig,\n callbacks?: BrowserCallbacks\n): Browser {\n const browser = new Browser(container, config, callbacks)\n browser.render()\n return browser\n}\n","/**\n * Calendar Component\n * カレンダーを表示し日付を選択するためのコンポーネント\n *\n * Features:\n * - 月表示カレンダー\n * - 日付選択\n * - 選択可能な日付範囲の制限 (from/to)\n * - 月移動ナビゲーション\n * - 今日の日付ハイライト\n * - キーボードナビゲーション\n */\n\nimport { createElement } from '../utils/dom'\nimport { createFieldWrapper } from '../utils/field-helpers'\nimport type { InputField } from '../../types/schema'\n\n// =============================================================================\n// Types\n// =============================================================================\n\n/**\n * カレンダーの状態\n */\nexport interface CalendarState {\n /** 現在選択されている日付 */\n value: Date | null\n /** 表示中の年月 */\n displayedMonth: Date\n /** フォーカスされている日付 */\n focusedDate: Date | null\n /** 無効化状態 */\n disabled: boolean\n}\n\n/**\n * カレンダーのコールバック\n */\nexport interface CalendarCallbacks {\n /** 日付選択時 */\n onSelectDate: (event: MouseEvent, date: Date, state: CalendarState) => void\n /** 月変更時 */\n onMonthChange?: (date: Date, state: CalendarState) => void\n}\n\n/**\n * カレンダーの設定\n */\nexport interface CalendarConfig {\n /** 初期選択日付 */\n value?: Date\n /** 選択可能な日付範囲の開始日 */\n from?: Date\n /** 選択可能な日付範囲の終了日 */\n to?: Date\n /** 無効化 */\n disabled?: boolean\n /** 週の開始曜日 (0: 日曜, 1: 月曜) */\n weekStartsOn?: 0 | 1\n /** ロケール */\n locale?: string\n /** aria-label */\n ariaLabel?: string\n}\n\n// =============================================================================\n// Calendar Class\n// =============================================================================\n\n/**\n * カレンダーコンポーネント\n */\nexport class Calendar {\n private config: CalendarConfig\n private state: CalendarState\n private callbacks: CalendarCallbacks\n private container: HTMLElement\n private calendarElement: HTMLElement | null = null\n\n constructor(\n container: HTMLElement,\n config: CalendarConfig = {},\n callbacks: CalendarCallbacks\n ) {\n this.config = config\n this.container = container\n this.callbacks = callbacks\n this.state = this.createInitialState()\n }\n\n // ===========================================================================\n // Public Methods\n // ===========================================================================\n\n /**\n * カレンダーをレンダリング\n */\n render(): void {\n this.container.innerHTML = ''\n this.container.className = 'mokkun-calendar'\n\n if (this.state.disabled) {\n this.container.setAttribute('data-disabled', '')\n } else {\n this.container.removeAttribute('data-disabled')\n }\n\n const calendar = createElement('div', {\n className: 'calendar-container',\n attributes: {\n role: 'application',\n 'aria-label': this.config.ariaLabel ?? 'カレンダー',\n },\n })\n\n // ヘッダー(月ナビゲーション)\n const header = this.renderHeader()\n calendar.appendChild(header)\n\n // カレンダーグリッド\n const grid = this.renderGrid()\n calendar.appendChild(grid)\n\n this.container.appendChild(calendar)\n this.calendarElement = calendar\n\n // キーボードイベント\n this.setupKeyboardNavigation()\n }\n\n /**\n * 選択日付を設定\n */\n setValue(value: Date | null): void {\n this.state = {\n ...this.state,\n value: value ? this.normalizeDate(value) : null,\n }\n if (value) {\n this.state.displayedMonth = this.getFirstDayOfMonth(value)\n }\n this.render()\n }\n\n /**\n * 選択日付を取得\n */\n getValue(): Date | null {\n return this.state.value\n }\n\n /**\n * 表示月を設定\n */\n setDisplayedMonth(date: Date): void {\n this.state = {\n ...this.state,\n displayedMonth: this.getFirstDayOfMonth(date),\n }\n this.render()\n this.callbacks.onMonthChange?.(this.state.displayedMonth, this.state)\n }\n\n /**\n * 無効化状態を設定\n */\n setDisabled(disabled: boolean): void {\n if (this.state.disabled === disabled) {\n return\n }\n this.state = {\n ...this.state,\n disabled,\n }\n this.render()\n }\n\n /**\n * 選択可能範囲を設定\n */\n setRange(from?: Date, to?: Date): void {\n this.config = {\n ...this.config,\n from: from ? this.normalizeDate(from) : undefined,\n to: to ? this.normalizeDate(to) : undefined,\n }\n this.render()\n }\n\n /**\n * 状態を取得\n */\n getState(): CalendarState {\n return { ...this.state }\n }\n\n /**\n * 破棄\n */\n destroy(): void {\n this.container.innerHTML = ''\n this.calendarElement = null\n }\n\n // ===========================================================================\n // Private Methods\n // ===========================================================================\n\n /**\n * 初期状態を作成\n */\n private createInitialState(): CalendarState {\n const value = this.config.value ? this.normalizeDate(this.config.value) : null\n const displayedMonth = value\n ? this.getFirstDayOfMonth(value)\n : this.getFirstDayOfMonth(new Date())\n\n return {\n value,\n displayedMonth,\n focusedDate: null,\n disabled: this.config.disabled ?? false,\n }\n }\n\n /**\n * ヘッダーをレンダリング\n */\n private renderHeader(): HTMLElement {\n const header = createElement('div', { className: 'calendar-header' })\n\n // 前月ボタン\n const prevButton = createElement('button', {\n className: 'calendar-nav-button calendar-prev',\n attributes: {\n type: 'button',\n 'aria-label': '前の月',\n ...(this.state.disabled && { disabled: 'disabled' }),\n },\n })\n prevButton.innerHTML = this.getChevronLeftIcon()\n prevButton.addEventListener('click', this.handlePrevMonth.bind(this))\n\n // 年月表示\n const monthLabel = createElement('div', {\n className: 'calendar-month-label',\n attributes: {\n 'aria-live': 'polite',\n },\n })\n monthLabel.textContent = this.formatMonthYear(this.state.displayedMonth)\n\n // 次月ボタン\n const nextButton = createElement('button', {\n className: 'calendar-nav-button calendar-next',\n attributes: {\n type: 'button',\n 'aria-label': '次の月',\n ...(this.state.disabled && { disabled: 'disabled' }),\n },\n })\n nextButton.innerHTML = this.getChevronRightIcon()\n nextButton.addEventListener('click', this.handleNextMonth.bind(this))\n\n header.appendChild(prevButton)\n header.appendChild(monthLabel)\n header.appendChild(nextButton)\n\n return header\n }\n\n /**\n * カレンダーグリッドをレンダリング\n */\n private renderGrid(): HTMLElement {\n const grid = createElement('div', {\n className: 'calendar-grid',\n attributes: {\n role: 'grid',\n 'aria-label': this.formatMonthYear(this.state.displayedMonth),\n },\n })\n\n // 曜日ヘッダー\n const weekdayRow = this.renderWeekdayHeader()\n grid.appendChild(weekdayRow)\n\n // 日付セル\n const weeks = this.getCalendarWeeks()\n for (const week of weeks) {\n const weekRow = this.renderWeekRow(week)\n grid.appendChild(weekRow)\n }\n\n return grid\n }\n\n /**\n * 曜日ヘッダーをレンダリング\n */\n private renderWeekdayHeader(): HTMLElement {\n const row = createElement('div', {\n className: 'calendar-weekdays',\n attributes: { role: 'row' },\n })\n\n const weekdays = this.getWeekdayLabels()\n for (const weekday of weekdays) {\n const cell = createElement('div', {\n className: 'calendar-weekday',\n attributes: {\n role: 'columnheader',\n 'aria-label': weekday.full,\n },\n textContent: weekday.short,\n })\n row.appendChild(cell)\n }\n\n return row\n }\n\n /**\n * 週の行をレンダリング\n */\n private renderWeekRow(week: (Date | null)[]): HTMLElement {\n const row = createElement('div', {\n className: 'calendar-week',\n attributes: { role: 'row' },\n })\n\n for (const date of week) {\n const cell = this.renderDateCell(date)\n row.appendChild(cell)\n }\n\n return row\n }\n\n /**\n * 日付セルをレンダリング\n */\n private renderDateCell(date: Date | null): HTMLElement {\n if (!date) {\n return createElement('div', {\n className: 'calendar-day calendar-day-empty',\n attributes: { role: 'gridcell' },\n })\n }\n\n const isToday = this.isToday(date)\n const isSelected = this.isSelected(date)\n const isDisabled = this.isDateDisabled(date)\n const isOutOfRange = !this.isDateInRange(date)\n const isCurrentMonth = date.getMonth() === this.state.displayedMonth.getMonth()\n\n const classNames = ['calendar-day']\n if (isToday) classNames.push('calendar-day-today')\n if (isSelected) classNames.push('calendar-day-selected')\n if (isDisabled || isOutOfRange) classNames.push('calendar-day-disabled')\n if (!isCurrentMonth) classNames.push('calendar-day-outside')\n\n const cell = createElement('button', {\n className: classNames.join(' '),\n attributes: {\n type: 'button',\n role: 'gridcell',\n tabindex: isSelected ? '0' : '-1',\n 'aria-label': this.formatDateFull(date),\n 'aria-selected': isSelected ? 'true' : 'false',\n 'aria-disabled': (isDisabled || isOutOfRange) ? 'true' : 'false',\n 'data-date': date.toISOString().split('T')[0],\n ...(isToday && { 'data-today': '' }),\n ...((isDisabled || isOutOfRange || this.state.disabled) && { disabled: 'disabled' }),\n },\n textContent: date.getDate().toString(),\n })\n\n if (!isDisabled && !isOutOfRange && !this.state.disabled) {\n cell.addEventListener('click', (e) => this.handleDateClick(e as MouseEvent, date))\n }\n\n return cell\n }\n\n /**\n * キーボードナビゲーションを設定\n */\n private setupKeyboardNavigation(): void {\n if (!this.calendarElement) return\n\n this.calendarElement.addEventListener('keydown', (e) => {\n if (this.state.disabled) return\n\n const key = e.key\n let newDate: Date | null = null\n const baseDate = this.state.focusedDate || this.state.value || new Date()\n\n switch (key) {\n case 'ArrowLeft':\n e.preventDefault()\n newDate = this.addDays(baseDate, -1)\n break\n case 'ArrowRight':\n e.preventDefault()\n newDate = this.addDays(baseDate, 1)\n break\n case 'ArrowUp':\n e.preventDefault()\n newDate = this.addDays(baseDate, -7)\n break\n case 'ArrowDown':\n e.preventDefault()\n newDate = this.addDays(baseDate, 7)\n break\n case 'Enter':\n case ' ':\n e.preventDefault()\n if (this.state.focusedDate && this.isDateInRange(this.state.focusedDate)) {\n const button = this.calendarElement?.querySelector(\n `[data-date=\"${this.state.focusedDate.toISOString().split('T')[0]}\"]`\n ) as HTMLButtonElement\n if (button) {\n button.click()\n }\n }\n break\n }\n\n if (newDate) {\n this.focusDate(newDate)\n }\n })\n }\n\n /**\n * 日付にフォーカス\n */\n private focusDate(date: Date): void {\n // 月が変わる場合は表示月も変更\n if (date.getMonth() !== this.state.displayedMonth.getMonth() ||\n date.getFullYear() !== this.state.displayedMonth.getFullYear()) {\n this.state.displayedMonth = this.getFirstDayOfMonth(date)\n this.state.focusedDate = date\n this.render()\n } else {\n this.state.focusedDate = date\n }\n\n // ボタンにフォーカス\n const button = this.container.querySelector(\n `[data-date=\"${date.toISOString().split('T')[0]}\"]`\n ) as HTMLButtonElement\n if (button) {\n button.focus()\n button.setAttribute('tabindex', '0')\n // 他のボタンのtabindexを-1に\n this.container.querySelectorAll('.calendar-day:not([data-date=\"' + date.toISOString().split('T')[0] + '\"])').forEach((el) => {\n el.setAttribute('tabindex', '-1')\n })\n }\n }\n\n // ===========================================================================\n // Event Handlers\n // ===========================================================================\n\n /**\n * 前月クリック\n */\n private handlePrevMonth(): void {\n if (this.state.disabled) return\n\n const newMonth = new Date(this.state.displayedMonth)\n newMonth.setMonth(newMonth.getMonth() - 1)\n this.state.displayedMonth = newMonth\n this.render()\n this.callbacks.onMonthChange?.(newMonth, this.state)\n }\n\n /**\n * 次月クリック\n */\n private handleNextMonth(): void {\n if (this.state.disabled) return\n\n const newMonth = new Date(this.state.displayedMonth)\n newMonth.setMonth(newMonth.getMonth() + 1)\n this.state.displayedMonth = newMonth\n this.render()\n this.callbacks.onMonthChange?.(newMonth, this.state)\n }\n\n /**\n * 日付クリック\n */\n private handleDateClick(event: MouseEvent, date: Date): void {\n if (this.state.disabled) return\n if (!this.isDateInRange(date)) return\n\n this.state = {\n ...this.state,\n value: date,\n focusedDate: date,\n }\n this.render()\n this.callbacks.onSelectDate(event, date, this.state)\n }\n\n // ===========================================================================\n // Utility Methods\n // ===========================================================================\n\n /**\n * 日付を正規化(時刻を0時0分0秒に)\n */\n private normalizeDate(date: Date): Date {\n const normalized = new Date(date)\n normalized.setHours(0, 0, 0, 0)\n return normalized\n }\n\n /**\n * 月の最初の日を取得\n */\n private getFirstDayOfMonth(date: Date): Date {\n return new Date(date.getFullYear(), date.getMonth(), 1)\n }\n\n /**\n * カレンダーの週を取得\n */\n private getCalendarWeeks(): (Date | null)[][] {\n const weeks: (Date | null)[][] = []\n const firstDay = this.getFirstDayOfMonth(this.state.displayedMonth)\n const lastDay = new Date(firstDay.getFullYear(), firstDay.getMonth() + 1, 0)\n const weekStartsOn = this.config.weekStartsOn ?? 0\n\n // 月の最初の週の開始日を計算\n let startDate = new Date(firstDay)\n const dayOfWeek = startDate.getDay()\n const diff = (dayOfWeek - weekStartsOn + 7) % 7\n startDate.setDate(startDate.getDate() - diff)\n\n // 6週分のカレンダーを生成\n for (let week = 0; week < 6; week++) {\n const weekDays: (Date | null)[] = []\n for (let day = 0; day < 7; day++) {\n const currentDate = new Date(startDate)\n currentDate.setDate(startDate.getDate() + (week * 7) + day)\n\n // 表示月外の日付も含める\n weekDays.push(currentDate)\n }\n weeks.push(weekDays)\n\n // 次の週が完全に次月の場合は終了\n const lastDayOfWeek = new Date(startDate)\n lastDayOfWeek.setDate(startDate.getDate() + (week * 7) + 6)\n if (lastDayOfWeek > lastDay && week >= 3) {\n const firstDayOfNextWeek = new Date(startDate)\n firstDayOfNextWeek.setDate(startDate.getDate() + ((week + 1) * 7))\n if (firstDayOfNextWeek.getMonth() !== firstDay.getMonth()) {\n break\n }\n }\n }\n\n return weeks\n }\n\n /**\n * 曜日ラベルを取得\n */\n private getWeekdayLabels(): { short: string; full: string }[] {\n const locale = this.config.locale ?? 'ja-JP'\n const weekStartsOn = this.config.weekStartsOn ?? 0\n const labels: { short: string; full: string }[] = []\n\n for (let i = 0; i < 7; i++) {\n const dayIndex = (i + weekStartsOn) % 7\n // 2024年1月7日は日曜日\n const date = new Date(2024, 0, 7 + dayIndex)\n labels.push({\n short: date.toLocaleDateString(locale, { weekday: 'short' }),\n full: date.toLocaleDateString(locale, { weekday: 'long' }),\n })\n }\n\n return labels\n }\n\n /**\n * 年月をフォーマット\n */\n private formatMonthYear(date: Date): string {\n const locale = this.config.locale ?? 'ja-JP'\n return date.toLocaleDateString(locale, { year: 'numeric', month: 'long' })\n }\n\n /**\n * 日付をフルフォーマット\n */\n private formatDateFull(date: Date): string {\n const locale = this.config.locale ?? 'ja-JP'\n return date.toLocaleDateString(locale, {\n year: 'numeric',\n month: 'long',\n day: 'numeric',\n weekday: 'long',\n })\n }\n\n /**\n * 今日かどうか\n */\n private isToday(date: Date): boolean {\n const today = this.normalizeDate(new Date())\n return date.getTime() === today.getTime()\n }\n\n /**\n * 選択されているかどうか\n */\n private isSelected(date: Date): boolean {\n if (!this.state.value) return false\n return date.getTime() === this.state.value.getTime()\n }\n\n /**\n * 日付が無効化されているかどうか\n */\n private isDateDisabled(_date: Date): boolean {\n return this.state.disabled\n }\n\n /**\n * 日付が範囲内かどうか\n */\n private isDateInRange(date: Date): boolean {\n const normalizedDate = this.normalizeDate(date)\n\n if (this.config.from) {\n const from = this.normalizeDate(this.config.from)\n if (normalizedDate < from) return false\n }\n\n if (this.config.to) {\n const to = this.normalizeDate(this.config.to)\n if (normalizedDate > to) return false\n }\n\n return true\n }\n\n /**\n * 日数を加算\n */\n private addDays(date: Date, days: number): Date {\n const result = new Date(date)\n result.setDate(result.getDate() + days)\n return this.normalizeDate(result)\n }\n\n /**\n * 左矢印アイコン\n */\n private getChevronLeftIcon(): string {\n return `<svg width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M10 12L6 8L10 4\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\n </svg>`\n }\n\n /**\n * 右矢印アイコン\n */\n private getChevronRightIcon(): string {\n return `<svg width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M6 12L10 8L6 4\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\n </svg>`\n }\n\n // ===========================================================================\n // Static Field Renderer\n // ===========================================================================\n\n static renderField(field: InputField): string {\n const calendarHtml = `\n <div class=\"mokkun-calendar calendar-placeholder\">\n <div class=\"calendar-header\">\n <button type=\"button\" class=\"calendar-nav-btn\" aria-label=\"前月\">←</button>\n <span class=\"calendar-month-year\">2024年12月</span>\n <button type=\"button\" class=\"calendar-nav-btn\" aria-label=\"次月\">→</button>\n </div>\n <div class=\"calendar-grid\">\n <div class=\"calendar-weekdays\">\n <span>日</span><span>月</span><span>火</span><span>水</span><span>木</span><span>金</span><span>土</span>\n </div>\n <div class=\"calendar-days\">\n ${Array.from({ length: 35 }, (_, i) => {\n const day = i - 5\n if (day < 1 || day > 31) return '<span class=\"calendar-day calendar-day-empty\"></span>'\n return `<span class=\"calendar-day ${day === 15 ? 'calendar-day-selected' : ''}\">${day}</span>`\n }).join('')}\n </div>\n </div>\n </div>\n `\n return createFieldWrapper(field, calendarHtml)\n }\n}\n\n// =============================================================================\n// Factory Function\n// =============================================================================\n\n/**\n * カレンダーコンポーネントを作成\n */\nexport function createCalendar(\n container: HTMLElement,\n config: CalendarConfig = {},\n callbacks: CalendarCallbacks\n): Calendar {\n const calendar = new Calendar(container, config, callbacks)\n calendar.render()\n return calendar\n}\n","/**\n * Tooltip Component\n * ツールチップコンポーネント\n *\n * \n * - 位置指定(top/bottom/left/right)\n * - 遅延表示(デフォルト300ms)\n * - リッチコンテンツ対応(HTML/テキスト)\n * - 矢印表示\n * - `role=\"tooltip\"` with `aria-describedby` for accessibility\n */\n\nimport { createElement, generateId } from '../utils/dom'\nimport { escapeHtml, createFieldWrapper } from '../utils/field-helpers'\nimport type { InputField } from '../../types/schema'\n\n// =============================================================================\n// Types\n// =============================================================================\n\n/**\n * ツールチップの位置\n */\nexport type TooltipPosition = 'top' | 'bottom' | 'left' | 'right'\n\n/**\n * ツールチップの状態\n */\nexport interface TooltipState {\n /** 表示中かどうか */\n visible: boolean\n /** ホバー中かどうか */\n hovering: boolean\n}\n\n/**\n * ツールチップのコールバック\n */\nexport interface TooltipCallbacks {\n /** 表示時 */\n onShow?: () => void\n /** 非表示時 */\n onHide?: () => void\n}\n\n/**\n * ツールチップの設定\n */\nexport interface TooltipConfig {\n /** ツールチップのコンテンツ(テキストまたはHTML) */\n content: string\n /** 位置(デフォルト: top) */\n position?: TooltipPosition\n /** 遅延表示時間(ミリ秒、デフォルト: 300) */\n delay?: number\n /** 矢印を表示するか(デフォルト: true) */\n showArrow?: boolean\n /** HTMLコンテンツとして解釈するか(デフォルト: false) */\n isHtml?: boolean\n /** 最大幅(デフォルト: 200px) */\n maxWidth?: string\n /** 無効化 */\n disabled?: boolean\n /** トリガー要素にdata-tooltip-triggerを追加するか */\n markTrigger?: boolean\n}\n\n// =============================================================================\n// Tooltip Class\n// =============================================================================\n\n/**\n * ツールチップコンポーネント\n */\nexport class Tooltip {\n private config: TooltipConfig\n private state: TooltipState\n private callbacks: TooltipCallbacks\n private triggerElement: HTMLElement\n private tooltipElement: HTMLElement | null = null\n private instanceId: string\n private showTimeout: number | null = null\n private hideTimeout: number | null = null\n\n constructor(\n triggerElement: HTMLElement,\n config: TooltipConfig,\n callbacks: TooltipCallbacks = {}\n ) {\n this.config = {\n position: 'top',\n delay: 300,\n showArrow: true,\n isHtml: false,\n maxWidth: '200px',\n disabled: false,\n markTrigger: true,\n ...config,\n }\n this.triggerElement = triggerElement\n this.callbacks = callbacks\n this.instanceId = generateId('tooltip')\n this.state = {\n visible: false,\n hovering: false,\n }\n\n this.initialize()\n }\n\n // ===========================================================================\n // Public Methods\n // ===========================================================================\n\n /**\n * ツールチップを表示\n */\n show(): void {\n if (this.config.disabled || this.state.visible) {\n return\n }\n\n // 遅延表示\n if (this.hideTimeout) {\n clearTimeout(this.hideTimeout)\n this.hideTimeout = null\n }\n\n this.showTimeout = window.setTimeout(() => {\n this.state = {\n ...this.state,\n visible: true,\n }\n this.render()\n this.callbacks.onShow?.()\n }, this.config.delay)\n }\n\n /**\n * ツールチップを非表示\n */\n hide(): void {\n if (this.showTimeout) {\n clearTimeout(this.showTimeout)\n this.showTimeout = null\n }\n\n // ホバー中でない場合のみ非表示\n if (!this.state.hovering) {\n this.hideTimeout = window.setTimeout(() => {\n this.state = {\n ...this.state,\n visible: false,\n }\n this.removeTooltip()\n this.callbacks.onHide?.()\n }, 100)\n }\n }\n\n /**\n * 即座にツールチップを表示(遅延なし)\n */\n showImmediate(): void {\n if (this.config.disabled) {\n return\n }\n\n if (this.showTimeout) {\n clearTimeout(this.showTimeout)\n this.showTimeout = null\n }\n\n this.state = {\n ...this.state,\n visible: true,\n }\n this.render()\n this.callbacks.onShow?.()\n }\n\n /**\n * 即座にツールチップを非表示(遅延なし)\n */\n hideImmediate(): void {\n if (this.showTimeout) {\n clearTimeout(this.showTimeout)\n this.showTimeout = null\n }\n if (this.hideTimeout) {\n clearTimeout(this.hideTimeout)\n this.hideTimeout = null\n }\n\n this.state = {\n ...this.state,\n visible: false,\n }\n this.removeTooltip()\n this.callbacks.onHide?.()\n }\n\n /**\n * ツールチップのコンテンツを更新\n */\n setContent(content: string): void {\n this.config = {\n ...this.config,\n content,\n }\n\n if (this.state.visible) {\n this.render()\n }\n }\n\n /**\n * ツールチップの位置を更新\n */\n setPosition(position: TooltipPosition): void {\n this.config = {\n ...this.config,\n position,\n }\n\n if (this.state.visible) {\n this.render()\n }\n }\n\n /**\n * 無効化状態を設定\n */\n setDisabled(disabled: boolean): void {\n this.config = {\n ...this.config,\n disabled,\n }\n\n if (disabled && this.state.visible) {\n this.hideImmediate()\n }\n }\n\n /**\n * ツールチップを破棄\n */\n destroy(): void {\n this.hideImmediate()\n this.removeEventListeners()\n\n if (this.config.markTrigger) {\n this.triggerElement.removeAttribute('data-tooltip-trigger')\n this.triggerElement.removeAttribute('aria-describedby')\n }\n }\n\n /**\n * 現在の状態を取得\n */\n getState(): TooltipState {\n return { ...this.state }\n }\n\n /**\n * 表示中かどうかを取得\n */\n isVisible(): boolean {\n return this.state.visible\n }\n\n // ===========================================================================\n // Private Methods\n // ===========================================================================\n\n /**\n * 初期化\n */\n private initialize(): void {\n // トリガー要素にdata-tooltip-trigger属性を追加\n if (this.config.markTrigger) {\n this.triggerElement.setAttribute('data-tooltip-trigger', '')\n this.triggerElement.setAttribute('aria-describedby', this.instanceId)\n }\n\n this.attachEventListeners()\n }\n\n /**\n * イベントリスナーを追加\n */\n private attachEventListeners(): void {\n this.triggerElement.addEventListener('mouseenter', this.handleMouseEnter)\n this.triggerElement.addEventListener('mouseleave', this.handleMouseLeave)\n this.triggerElement.addEventListener('focus', this.handleFocus)\n this.triggerElement.addEventListener('blur', this.handleBlur)\n }\n\n /**\n * イベントリスナーを削除\n */\n private removeEventListeners(): void {\n this.triggerElement.removeEventListener('mouseenter', this.handleMouseEnter)\n this.triggerElement.removeEventListener('mouseleave', this.handleMouseLeave)\n this.triggerElement.removeEventListener('focus', this.handleFocus)\n this.triggerElement.removeEventListener('blur', this.handleBlur)\n }\n\n /**\n * マウスエンターハンドラー\n */\n private handleMouseEnter = (): void => {\n this.state = {\n ...this.state,\n hovering: true,\n }\n this.show()\n }\n\n /**\n * マウスリーブハンドラー\n */\n private handleMouseLeave = (): void => {\n this.state = {\n ...this.state,\n hovering: false,\n }\n this.hide()\n }\n\n /**\n * フォーカスハンドラー\n */\n private handleFocus = (): void => {\n this.show()\n }\n\n /**\n * ブラーハンドラー\n */\n private handleBlur = (): void => {\n this.hide()\n }\n\n /**\n * ツールチップをレンダリング\n */\n private render(): void {\n // 既存のツールチップを即座に削除\n this.removeTooltipImmediate()\n\n // ツールチップ要素を作成\n this.tooltipElement = createElement('div', {\n className: `mokkun-tooltip tooltip-${this.config.position}`,\n attributes: {\n id: this.instanceId,\n role: 'tooltip',\n 'data-position': this.config.position ?? 'top',\n },\n })\n\n // スタイルを設定\n this.tooltipElement.style.maxWidth = this.config.maxWidth ?? '200px'\n\n // 矢印を追加\n if (this.config.showArrow) {\n const arrow = createElement('div', {\n className: 'tooltip-arrow',\n attributes: {\n 'data-position': this.config.position ?? 'top',\n },\n })\n this.tooltipElement.appendChild(arrow)\n }\n\n // コンテンツを追加\n const content = createElement('div', {\n className: 'tooltip-content',\n })\n\n if (this.config.isHtml) {\n content.innerHTML = this.config.content\n } else {\n content.textContent = this.config.content\n }\n\n this.tooltipElement.appendChild(content)\n\n // body に追加\n document.body.appendChild(this.tooltipElement)\n\n // 位置を計算して設定\n this.positionTooltip()\n\n // ツールチップ自体のマウスイベント\n this.tooltipElement.addEventListener('mouseenter', () => {\n if (this.hideTimeout) {\n clearTimeout(this.hideTimeout)\n this.hideTimeout = null\n }\n })\n\n this.tooltipElement.addEventListener('mouseleave', () => {\n this.hide()\n })\n\n // アニメーション用のクラスを追加(次のフレームで)\n requestAnimationFrame(() => {\n this.tooltipElement?.classList.add('tooltip-visible')\n })\n }\n\n /**\n * ツールチップの位置を計算して設定\n */\n private positionTooltip(): void {\n if (!this.tooltipElement) {\n return\n }\n\n const triggerRect = this.triggerElement.getBoundingClientRect()\n const tooltipRect = this.tooltipElement.getBoundingClientRect()\n const position = this.config.position ?? 'top'\n const gap = 8 // トリガー要素とツールチップの間隔\n\n let top = 0\n let left = 0\n\n switch (position) {\n case 'top':\n top = triggerRect.top + window.scrollY - tooltipRect.height - gap\n left = triggerRect.left + window.scrollX + (triggerRect.width - tooltipRect.width) / 2\n break\n\n case 'bottom':\n top = triggerRect.bottom + window.scrollY + gap\n left = triggerRect.left + window.scrollX + (triggerRect.width - tooltipRect.width) / 2\n break\n\n case 'left':\n top = triggerRect.top + window.scrollY + (triggerRect.height - tooltipRect.height) / 2\n left = triggerRect.left + window.scrollX - tooltipRect.width - gap\n break\n\n case 'right':\n top = triggerRect.top + window.scrollY + (triggerRect.height - tooltipRect.height) / 2\n left = triggerRect.right + window.scrollX + gap\n break\n }\n\n // ビューポート外に出ないように調整\n const viewportWidth = window.innerWidth\n const viewportHeight = window.innerHeight\n\n // 左右の調整\n if (left < 0) {\n left = 8\n } else if (left + tooltipRect.width > viewportWidth) {\n left = viewportWidth - tooltipRect.width - 8\n }\n\n // 上下の調整\n if (top < window.scrollY) {\n top = window.scrollY + 8\n } else if (top + tooltipRect.height > window.scrollY + viewportHeight) {\n top = window.scrollY + viewportHeight - tooltipRect.height - 8\n }\n\n this.tooltipElement.style.top = `${top}px`\n this.tooltipElement.style.left = `${left}px`\n }\n\n /**\n * ツールチップを削除\n */\n private removeTooltip(): void {\n if (this.tooltipElement) {\n this.tooltipElement.classList.remove('tooltip-visible')\n\n // アニメーション後に削除\n setTimeout(() => {\n if (this.tooltipElement && this.tooltipElement.parentNode) {\n this.tooltipElement.parentNode.removeChild(this.tooltipElement)\n }\n this.tooltipElement = null\n }, 200)\n }\n }\n\n /**\n * ツールチップを即座に削除(アニメーションなし)\n */\n private removeTooltipImmediate(): void {\n if (this.tooltipElement && this.tooltipElement.parentNode) {\n this.tooltipElement.parentNode.removeChild(this.tooltipElement)\n this.tooltipElement = null\n }\n }\n\n // ===========================================================================\n // Static Field Renderer\n // ===========================================================================\n\n static renderField(field: InputField): string {\n const tooltipField = field as InputField & {\n text?: string\n content?: string\n }\n const text = tooltipField.text ?? 'ヘルプ'\n const content = tooltipField.content ?? 'ツールチップの内容'\n\n const tooltipHtml = `\n <div class=\"mokkun-tooltip-container\">\n <span class=\"tooltip-trigger\" tabindex=\"0\" aria-describedby=\"${escapeHtml(field.id)}-tooltip\">${escapeHtml(text)}</span>\n <div class=\"tooltip-content\" id=\"${escapeHtml(field.id)}-tooltip\" role=\"tooltip\">${escapeHtml(content)}</div>\n </div>\n `\n return createFieldWrapper(field, tooltipHtml)\n }\n}\n\n// =============================================================================\n// Factory Function\n// =============================================================================\n\n/**\n * Tooltipを作成するファクトリ関数\n */\nexport function createTooltip(\n triggerElement: HTMLElement,\n config: TooltipConfig,\n callbacks: TooltipCallbacks = {}\n): Tooltip {\n return new Tooltip(triggerElement, config, callbacks)\n}\n","/**\n * FloatArea Component\n * フローティング領域コンポーネント\n *\n * \n * https://smarthr.design/products/components/float-area/\n *\n * 機能:\n * - primaryButton / secondaryButton / tertiaryButton の3ボタン構成\n * - responseMessage(処理結果メッセージ)のサポート\n * - 画面下部への固定表示\n * - デスクトップ/モバイル対応レイアウト\n * - z-index管理\n *\n * 用途:\n * - フォーム送信ボタンの固定表示\n * - モーダルUIのアクション領域\n * - 設定画面のアクションビュー\n */\n\nimport { createElement, generateId } from '../utils/dom'\nimport { createFieldWrapper } from '../utils/field-helpers'\nimport type { InputField } from '../../types/schema'\n\n// =============================================================================\n// Types\n// =============================================================================\n\n/**\n * ボタン設定\n */\nexport interface FloatAreaButton {\n /** ボタンのラベル */\n label: string\n /** ボタンのタイプ */\n variant?: 'primary' | 'secondary' | 'danger' | 'text'\n /** 無効状態 */\n disabled?: boolean\n /** クリック時のコールバック */\n onClick?: () => void\n}\n\n/**\n * レスポンスメッセージの種類\n */\nexport type ResponseMessageType = 'success' | 'error' | 'warning' | 'info'\n\n/**\n * レスポンスメッセージ設定\n */\nexport interface ResponseMessage {\n /** メッセージ */\n text: string\n /** メッセージの種類 */\n type: ResponseMessageType\n}\n\n/**\n * フローティング領域の状態\n */\nexport interface FloatAreaState {\n /** 表示中かどうか */\n visible: boolean\n /** z-index */\n zIndex: number\n /** レスポンスメッセージ */\n responseMessage: ResponseMessage | null\n}\n\n/**\n * フローティング領域のコールバック\n */\nexport interface FloatAreaCallbacks {\n /** プライマリボタンクリック時 */\n onPrimaryClick?: () => void\n /** セカンダリボタンクリック時 */\n onSecondaryClick?: () => void\n /** ターシャリボタンクリック時 */\n onTertiaryClick?: () => void\n /** 表示時 */\n onShow?: () => void\n /** 非表示時 */\n onHide?: () => void\n}\n\n/**\n * フローティング領域の設定\n */\nexport interface FloatAreaConfig {\n /** プライマリボタン(必須) */\n primaryButton: FloatAreaButton\n /** セカンダリボタン */\n secondaryButton?: FloatAreaButton\n /** ターシャリボタン(左端に配置) */\n tertiaryButton?: FloatAreaButton\n /** レスポンスメッセージ */\n responseMessage?: ResponseMessage\n /** z-index(デフォルト: 500) */\n zIndex?: number\n /** 下部からの距離(デフォルト: 24px) */\n bottom?: string\n /** 最大幅(デフォルト: 800px) */\n maxWidth?: string\n /** アクセシビリティ用ラベル */\n ariaLabel?: string\n}\n\n// =============================================================================\n// FloatArea Class\n// =============================================================================\n\n/**\n * フローティング領域コンポーネント\n */\nexport class FloatArea {\n private config: FloatAreaConfig\n private state: FloatAreaState\n private callbacks: FloatAreaCallbacks\n private containerElement: HTMLElement\n private floatAreaElement: HTMLElement | null = null\n private instanceId: string\n\n constructor(\n containerElement: HTMLElement,\n config: FloatAreaConfig,\n callbacks: FloatAreaCallbacks = {}\n ) {\n this.config = {\n zIndex: 500,\n bottom: '24px',\n maxWidth: '800px',\n ...config,\n }\n this.containerElement = containerElement\n this.callbacks = callbacks\n this.instanceId = generateId('float-area')\n this.state = {\n visible: true,\n zIndex: this.config.zIndex ?? 500,\n responseMessage: this.config.responseMessage ?? null,\n }\n }\n\n // ===========================================================================\n // Public Methods\n // ===========================================================================\n\n /**\n * コンポーネントをレンダリング\n */\n render(): void {\n this.removeElement()\n this.createFloatAreaElement()\n }\n\n /**\n * フローティング領域を表示\n */\n show(): void {\n if (this.state.visible) {\n return\n }\n\n this.state = {\n ...this.state,\n visible: true,\n }\n this.updateVisibility()\n this.callbacks.onShow?.()\n }\n\n /**\n * フローティング領域を非表示\n */\n hide(): void {\n if (!this.state.visible) {\n return\n }\n\n this.state = {\n ...this.state,\n visible: false,\n }\n this.updateVisibility()\n this.callbacks.onHide?.()\n }\n\n /**\n * 表示/非表示を切り替え\n */\n toggle(): void {\n if (this.state.visible) {\n this.hide()\n } else {\n this.show()\n }\n }\n\n /**\n * レスポンスメッセージを設定\n */\n setResponseMessage(message: ResponseMessage | null): void {\n this.state = {\n ...this.state,\n responseMessage: message,\n }\n this.render()\n }\n\n /**\n * 成功メッセージを表示\n */\n showSuccess(text: string): void {\n this.setResponseMessage({ text, type: 'success' })\n }\n\n /**\n * エラーメッセージを表示\n */\n showError(text: string): void {\n this.setResponseMessage({ text, type: 'error' })\n }\n\n /**\n * メッセージをクリア\n */\n clearMessage(): void {\n this.setResponseMessage(null)\n }\n\n /**\n * プライマリボタンを更新\n */\n updatePrimaryButton(button: Partial<FloatAreaButton>): void {\n this.config = {\n ...this.config,\n primaryButton: {\n ...this.config.primaryButton,\n ...button,\n },\n }\n this.render()\n }\n\n /**\n * プライマリボタンの無効状態を設定\n */\n setPrimaryDisabled(disabled: boolean): void {\n this.updatePrimaryButton({ disabled })\n }\n\n /**\n * z-indexを設定\n */\n setZIndex(zIndex: number): void {\n this.state = {\n ...this.state,\n zIndex,\n }\n if (this.floatAreaElement) {\n this.floatAreaElement.style.zIndex = String(zIndex)\n }\n }\n\n /**\n * コンポーネントを破棄\n */\n destroy(): void {\n this.removeElement()\n }\n\n /**\n * 現在の状態を取得\n */\n getState(): FloatAreaState {\n return { ...this.state }\n }\n\n /**\n * 表示中かどうかを取得\n */\n isVisible(): boolean {\n return this.state.visible\n }\n\n // ===========================================================================\n // Private Methods\n // ===========================================================================\n\n /**\n * フローティング領域要素を作成\n */\n private createFloatAreaElement(): void {\n this.floatAreaElement = createElement('div', {\n className: this.buildClassName(),\n attributes: {\n id: this.instanceId,\n role: 'region',\n 'aria-label': this.config.ariaLabel ?? 'アクション',\n 'aria-hidden': String(!this.state.visible),\n },\n })\n\n // スタイルを設定\n this.floatAreaElement.style.zIndex = String(this.state.zIndex)\n if (this.config.bottom) {\n this.floatAreaElement.style.setProperty('--float-area-bottom', this.config.bottom)\n }\n if (this.config.maxWidth) {\n this.floatAreaElement.style.setProperty('--float-area-max-width', this.config.maxWidth)\n }\n\n // 内部コンテナを作成\n const innerContainer = createElement('div', {\n className: 'float-area-inner',\n })\n\n // ターシャリボタン(左端)\n if (this.config.tertiaryButton) {\n const tertiaryWrapper = createElement('div', {\n className: 'float-area-tertiary',\n })\n tertiaryWrapper.appendChild(this.createButton(this.config.tertiaryButton, 'tertiary'))\n innerContainer.appendChild(tertiaryWrapper)\n }\n\n // メイン領域(メッセージ + ボタン)\n const mainArea = createElement('div', {\n className: 'float-area-main',\n })\n\n // レスポンスメッセージ\n if (this.state.responseMessage) {\n const messageEl = this.createResponseMessage(this.state.responseMessage)\n mainArea.appendChild(messageEl)\n }\n\n // ボタングループ(プライマリ + セカンダリ)\n const buttonGroup = createElement('div', {\n className: 'float-area-buttons',\n })\n\n // セカンダリボタン(先に追加 = 左側)\n if (this.config.secondaryButton) {\n buttonGroup.appendChild(this.createButton(this.config.secondaryButton, 'secondary'))\n }\n\n // プライマリボタン(後に追加 = 右側)\n buttonGroup.appendChild(this.createButton(this.config.primaryButton, 'primary'))\n\n mainArea.appendChild(buttonGroup)\n innerContainer.appendChild(mainArea)\n\n this.floatAreaElement.appendChild(innerContainer)\n this.containerElement.appendChild(this.floatAreaElement)\n }\n\n /**\n * ボタン要素を作成\n */\n private createButton(config: FloatAreaButton, type: 'primary' | 'secondary' | 'tertiary'): HTMLButtonElement {\n const variant = config.variant ?? (type === 'primary' ? 'primary' : type === 'tertiary' ? 'text' : 'secondary')\n\n const button = document.createElement('button')\n button.type = 'button'\n button.className = `float-area-btn float-area-btn-${variant}`\n button.textContent = config.label\n button.disabled = config.disabled ?? false\n\n if (config.disabled) {\n button.setAttribute('aria-disabled', 'true')\n }\n\n button.addEventListener('click', () => {\n if (config.disabled) return\n\n config.onClick?.()\n\n // コールバックを呼び出し\n if (type === 'primary') {\n this.callbacks.onPrimaryClick?.()\n } else if (type === 'secondary') {\n this.callbacks.onSecondaryClick?.()\n } else {\n this.callbacks.onTertiaryClick?.()\n }\n })\n\n return button\n }\n\n /**\n * レスポンスメッセージ要素を作成\n */\n private createResponseMessage(message: ResponseMessage): HTMLElement {\n const messageEl = createElement('div', {\n className: `float-area-message float-area-message-${message.type}`,\n attributes: {\n role: message.type === 'error' ? 'alert' : 'status',\n 'aria-live': 'polite',\n },\n })\n\n // アイコン\n const icon = this.getMessageIcon(message.type)\n const iconEl = createElement('span', {\n className: 'float-area-message-icon',\n })\n iconEl.innerHTML = icon\n messageEl.appendChild(iconEl)\n\n // テキスト\n const textEl = createElement('span', {\n className: 'float-area-message-text',\n })\n textEl.textContent = message.text\n messageEl.appendChild(textEl)\n\n return messageEl\n }\n\n /**\n * メッセージタイプに応じたアイコンを取得\n */\n private getMessageIcon(type: ResponseMessageType): string {\n switch (type) {\n case 'success':\n return '<svg width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"currentColor\"><path d=\"M8 0a8 8 0 1 0 0 16A8 8 0 0 0 8 0zm3.78 5.22a.75.75 0 0 1 0 1.06l-4.5 4.5a.75.75 0 0 1-1.06 0l-2-2a.75.75 0 0 1 1.06-1.06L6.75 9.19l3.97-3.97a.75.75 0 0 1 1.06 0z\"/></svg>'\n case 'error':\n return '<svg width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"currentColor\"><path d=\"M8 0a8 8 0 1 0 0 16A8 8 0 0 0 8 0zm0 3a.75.75 0 0 1 .75.75v4.5a.75.75 0 0 1-1.5 0v-4.5A.75.75 0 0 1 8 3zm0 8a1 1 0 1 1 0-2 1 1 0 0 1 0 2z\"/></svg>'\n case 'warning':\n return '<svg width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"currentColor\"><path d=\"M8.22 1.754a.25.25 0 0 0-.44 0L1.698 13.132a.25.25 0 0 0 .22.368h12.164a.25.25 0 0 0 .22-.368L8.22 1.754zm-1.763-.707c.659-1.234 2.427-1.234 3.086 0l6.082 11.378A1.75 1.75 0 0 1 14.082 15H1.918a1.75 1.75 0 0 1-1.543-2.575L6.457 1.047zM9 11a1 1 0 1 1-2 0 1 1 0 0 1 2 0zm-.25-5.25a.75.75 0 0 0-1.5 0v2.5a.75.75 0 0 0 1.5 0v-2.5z\"/></svg>'\n case 'info':\n return '<svg width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"currentColor\"><path d=\"M8 0a8 8 0 1 0 0 16A8 8 0 0 0 8 0zm.75 4.75a.75.75 0 0 1-1.5 0 .75.75 0 0 1 1.5 0zM7 7a.75.75 0 0 1 .75-.75h.5a.75.75 0 0 1 .75.75v3.25h.25a.75.75 0 0 1 0 1.5h-2a.75.75 0 0 1 0-1.5H7V7.75A.75.75 0 0 1 7 7z\"/></svg>'\n }\n }\n\n /**\n * クラス名を構築\n */\n private buildClassName(): string {\n const classNames = ['mokkun-float-area']\n\n if (!this.state.visible) {\n classNames.push('float-area-hidden')\n }\n\n return classNames.join(' ')\n }\n\n /**\n * 表示状態を更新\n */\n private updateVisibility(): void {\n if (!this.floatAreaElement) {\n return\n }\n\n if (this.state.visible) {\n this.floatAreaElement.classList.remove('float-area-hidden')\n this.floatAreaElement.setAttribute('aria-hidden', 'false')\n } else {\n this.floatAreaElement.classList.add('float-area-hidden')\n this.floatAreaElement.setAttribute('aria-hidden', 'true')\n }\n }\n\n /**\n * 要素を削除\n */\n private removeElement(): void {\n if (this.floatAreaElement && this.floatAreaElement.parentNode) {\n this.floatAreaElement.parentNode.removeChild(this.floatAreaElement)\n }\n this.floatAreaElement = null\n }\n\n // ===========================================================================\n // Static Field Renderer\n // ===========================================================================\n\n static renderField(field: InputField): string {\n const floatAreaHtml = `\n <div class=\"mokkun-float-area\">\n <div class=\"float-area-content\">\n <span class=\"float-area-placeholder\">[フロートエリア]</span>\n </div>\n </div>\n `\n return createFieldWrapper(field, floatAreaHtml)\n }\n}\n\n// =============================================================================\n// Factory Function\n// =============================================================================\n\n/**\n * FloatAreaを作成するファクトリ関数\n */\nexport function createFloatArea(\n containerElement: HTMLElement,\n config: FloatAreaConfig,\n callbacks: FloatAreaCallbacks = {}\n): FloatArea {\n return new FloatArea(containerElement, config, callbacks)\n}\n\n// =============================================================================\n// Type Exports (for backwards compatibility)\n// =============================================================================\n\nexport type FloatAreaPosition = 'top' | 'bottom'\nexport type FloatAreaAlignment = 'left' | 'center' | 'right' | 'space-between'\n","/**\n * Loader Component\n * ローディングインジケーターコンポーネント\n *\n * 機能:\n * - サイズバリエーション (small/medium/large)\n * - カラータイプ (primary/light)\n * - インライン/オーバーレイ表示\n * - プログレスバー対応\n * - アクセシビリティ対応 (role=\"status\", aria-busy, aria-live)\n */\n\nimport { createElement, generateId } from '../utils/dom'\nimport { escapeHtml, createFieldWrapper } from '../utils/field-helpers'\nimport type {\n LoaderConfig,\n LoaderState,\n LoaderCallbacks,\n InputField,\n} from '../../types/schema'\n\n// Re-export types for convenience\nexport type { LoaderConfig, LoaderState, LoaderCallbacks } from '../../types/schema'\n\n// =============================================================================\n// Loader Class\n// =============================================================================\n\n/**\n * Loaderコンポーネント\n * 読み込み中を示すスピナー/プログレス表示\n */\nexport class Loader {\n private config: LoaderConfig\n private state: LoaderState\n private callbacks: LoaderCallbacks\n private container: HTMLElement | null\n private instanceId: string\n\n // DOM elements\n private loaderElement: HTMLElement | null = null\n private overlayElement: HTMLElement | null = null\n private spinnerElement: HTMLElement | null = null\n private textElement: HTMLElement | null = null\n private progressBarContainer: HTMLElement | null = null\n private progressBarFill: HTMLElement | null = null\n\n constructor(\n container: HTMLElement | null,\n config: LoaderConfig = {},\n callbacks: LoaderCallbacks = {}\n ) {\n this.container = container\n this.config = {\n size: 'medium',\n type: 'primary',\n overlay: false,\n ariaLabel: 'Loading',\n ...config,\n }\n this.callbacks = callbacks\n this.instanceId = generateId('loader')\n this.state = this.createInitialState()\n\n // Auto-show if configured\n if (this.config.autoShow) {\n setTimeout(() => this.show(), 0)\n }\n }\n\n // ===========================================================================\n // Public API\n // ===========================================================================\n\n /**\n * ローダーを表示\n */\n show(): void {\n if (this.state.isVisible) {\n return\n }\n\n this.state = {\n ...this.state,\n isVisible: true,\n }\n\n this.render()\n this.callbacks.onShow?.()\n }\n\n /**\n * ローダーを非表示\n */\n hide(): void {\n if (!this.state.isVisible) {\n return\n }\n\n this.state = {\n ...this.state,\n isVisible: false,\n }\n\n this.cleanup()\n this.callbacks.onHide?.()\n }\n\n /**\n * プログレス値を更新 (0-100)\n */\n setProgress(value: number): void {\n // Clamp value to 0-100\n const clampedValue = Math.max(0, Math.min(100, value))\n\n this.state = {\n ...this.state,\n progress: clampedValue,\n }\n\n // Update progress bar if visible\n if (this.state.isVisible && this.progressBarFill) {\n this.updateProgressBar(clampedValue)\n }\n\n this.callbacks.onProgressUpdate?.(clampedValue)\n }\n\n /**\n * テキストを更新\n */\n setText(text: string): void {\n this.state = {\n ...this.state,\n text,\n }\n\n // Update text element if visible\n if (this.state.isVisible && this.textElement) {\n this.textElement.textContent = text\n }\n }\n\n /**\n * 現在の状態を取得(イミュータブル)\n */\n getState(): Readonly<LoaderState> {\n return { ...this.state }\n }\n\n /**\n * ローダーを破棄\n */\n destroy(): void {\n this.cleanup()\n this.state = {\n ...this.state,\n isVisible: false,\n }\n }\n\n // ===========================================================================\n // Private Methods - Rendering\n // ===========================================================================\n\n /**\n * ローダーをレンダリング\n */\n private render(): void {\n if (this.config.overlay) {\n this.renderOverlay()\n } else {\n this.renderInline()\n }\n }\n\n /**\n * インライン表示\n */\n private renderInline(): void {\n if (!this.container) {\n console.warn('Loader: No container provided for inline mode')\n return\n }\n\n // Create loader element\n this.loaderElement = this.createLoaderElement()\n\n // Clear container and append loader\n this.container.innerHTML = ''\n this.container.appendChild(this.loaderElement)\n }\n\n /**\n * オーバーレイ表示\n */\n private renderOverlay(): void {\n // Create overlay backdrop\n this.overlayElement = createElement('div', {\n className: 'loader-overlay',\n attributes: {\n role: 'status',\n 'aria-modal': 'true',\n 'aria-busy': 'true',\n 'aria-label': this.config.ariaLabel || 'Loading',\n },\n })\n\n // Create centered content container\n const contentContainer = createElement('div', {\n className: 'loader-overlay-content',\n })\n\n // Create loader element\n this.loaderElement = this.createLoaderElement()\n contentContainer.appendChild(this.loaderElement)\n\n this.overlayElement.appendChild(contentContainer)\n\n // Append to body and prevent scroll\n document.body.appendChild(this.overlayElement)\n document.body.classList.add('loader-open')\n }\n\n /**\n * ローダー要素を作成\n */\n private createLoaderElement(): HTMLElement {\n const container = createElement('div', {\n className: 'mokkun-loader',\n attributes: {\n id: this.instanceId,\n },\n })\n\n // Add spinner\n this.spinnerElement = this.createSpinner()\n container.appendChild(this.spinnerElement)\n\n // Add text if provided\n if (this.config.text || this.state.text) {\n this.textElement = this.createText()\n container.appendChild(this.textElement)\n }\n\n // Add progress bar if progress is set\n if (this.config.progress !== undefined || this.state.progress !== undefined) {\n const progressContainer = this.createProgressBar()\n container.appendChild(progressContainer)\n }\n\n // Set ARIA attributes for inline mode\n if (!this.config.overlay) {\n container.setAttribute('role', 'status')\n container.setAttribute('aria-label', this.config.ariaLabel || 'Loading')\n }\n\n return container\n }\n\n /**\n * スピナー要素を作成\n */\n private createSpinner(): HTMLElement {\n const size = this.config.size || 'medium'\n const type = this.config.type || 'primary'\n\n const spinner = createElement('div', {\n className: 'loader-spinner',\n attributes: {\n 'data-size': size,\n 'data-type': type,\n 'aria-hidden': 'true', // Decorative element\n },\n })\n\n return spinner\n }\n\n /**\n * テキスト要素を作成\n */\n private createText(): HTMLElement {\n const text = this.state.text || this.config.text || ''\n\n const textElement = createElement('div', {\n className: 'loader-text',\n textContent: text,\n attributes: {\n 'aria-live': 'polite', // Announce text changes\n },\n })\n\n return textElement\n }\n\n /**\n * プログレスバーを作成\n */\n private createProgressBar(): HTMLElement {\n const progress = this.state.progress ?? this.config.progress ?? 0\n\n this.progressBarContainer = createElement('div', {\n className: 'loader-progress',\n attributes: {\n role: 'progressbar',\n 'aria-valuemin': '0',\n 'aria-valuemax': '100',\n 'aria-valuenow': String(progress),\n },\n })\n\n this.progressBarFill = createElement('div', {\n className: 'loader-progress-fill',\n })\n\n this.progressBarFill.style.width = `${progress}%`\n\n this.progressBarContainer.appendChild(this.progressBarFill)\n\n return this.progressBarContainer\n }\n\n /**\n * プログレスバーを更新\n */\n private updateProgressBar(progress: number): void {\n if (this.progressBarFill) {\n this.progressBarFill.style.width = `${progress}%`\n }\n\n if (this.progressBarContainer) {\n this.progressBarContainer.setAttribute('aria-valuenow', String(progress))\n }\n }\n\n // ===========================================================================\n // Private Methods - State Management\n // ===========================================================================\n\n /**\n * 初期状態を作成\n */\n private createInitialState(): LoaderState {\n return {\n isVisible: false,\n progress: this.config.progress,\n text: this.config.text,\n }\n }\n\n /**\n * クリーンアップ\n */\n private cleanup(): void {\n // Remove overlay from body\n if (this.overlayElement) {\n this.overlayElement.remove()\n this.overlayElement = null\n document.body.classList.remove('loader-open')\n }\n\n // Remove inline loader\n if (this.loaderElement && !this.config.overlay) {\n this.loaderElement.remove()\n this.loaderElement = null\n }\n\n // Clear references\n this.spinnerElement = null\n this.textElement = null\n this.progressBarContainer = null\n this.progressBarFill = null\n }\n\n // ===========================================================================\n // Static Field Renderer\n // ===========================================================================\n\n /**\n * LoaderフィールドをHTMLとしてレンダリング(静的メソッド)\n * SSR/初期レンダリング用\n */\n static renderField(field: InputField): string {\n const loaderField = field as InputField & {\n size?: 'small' | 'medium' | 'large'\n text?: string\n }\n const size = loaderField.size ?? 'medium'\n const text = loaderField.text\n\n const loaderHtml = `\n <div class=\"mokkun-loader loader-${size}\">\n <div class=\"loader-spinner\"></div>\n ${text ? `<span class=\"loader-text\">${escapeHtml(text)}</span>` : ''}\n </div>\n `\n\n return createFieldWrapper(field, loaderHtml)\n }\n}\n\n// =============================================================================\n// Factory Function\n// =============================================================================\n\n/**\n * Loaderを作成\n */\nexport function createLoader(\n container: HTMLElement | null,\n config: LoaderConfig = {},\n callbacks: LoaderCallbacks = {}\n): Loader {\n return new Loader(container, config, callbacks)\n}\n","/**\n * NotificationBar Component\n * 通知バーコンポーネント\n *\n * \n * - タイプ(info/success/warning/error/sync)\n * - アクションボタン対応\n * - 閉じるボタン\n * - アニメーション(スライドイン)\n * - 複数通知のスタック表示対応\n * - `data-type` for styling\n * - `role=\"alert\"` or `role=\"status\"` for accessibility\n *\n * @see https://smarthr.design/products/components/notification-bar/\n */\n\nimport { createElement, generateId } from '../utils/dom'\nimport { escapeHtml, createFieldWrapper } from '../utils/field-helpers'\nimport type { InputField } from '../../types/schema'\n\n// =============================================================================\n// Types\n// =============================================================================\n\n/**\n * 通知バーのタイプ\n * - info: 情報通知\n * - success: 成功通知\n * - warning: 警告通知\n * - error: エラー通知\n * - sync: 同期中通知\n */\nexport type NotificationBarType = 'info' | 'success' | 'warning' | 'error' | 'sync'\n\n/**\n * 通知バーの状態\n */\nexport interface NotificationBarState {\n /** メッセージ */\n message: string\n /** 表示状態 */\n visible: boolean\n /** 強調表示 */\n bold: boolean\n}\n\n/**\n * 通知バーのコールバック\n */\nexport interface NotificationBarCallbacks {\n /** 閉じるボタンクリック時 */\n onClose?: () => void\n /** アクションボタンクリック時 */\n onAction?: () => void\n}\n\n/**\n * 通知バーの設定\n */\nexport interface NotificationBarConfig {\n /** メッセージ */\n message: string\n /** タイプ(カラー) */\n type?: NotificationBarType\n /** アクションボタンのラベル */\n actionLabel?: string\n /** 閉じるボタンを表示するか */\n closable?: boolean\n /** 強調表示(背景色を濃くする) */\n bold?: boolean\n /** アクセシビリティ用のロール */\n role?: 'alert' | 'status'\n /** アクセシビリティ用のラベル */\n ariaLabel?: string\n}\n\n// =============================================================================\n// Built-in Icons\n// =============================================================================\n\nconst BUILTIN_ICONS: Record<NotificationBarType, string> = {\n info: `<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 16 16\" fill=\"currentColor\" aria-hidden=\"true\"><path fill-rule=\"evenodd\" d=\"M15 8A7 7 0 1 1 1 8a7 7 0 0 1 14 0ZM9 5a1 1 0 1 1-2 0 1 1 0 0 1 2 0ZM6.75 8a.75.75 0 0 0 0 1.5h.75v1.75a.75.75 0 0 0 1.5 0v-2.5A.75.75 0 0 0 8.25 8h-1.5Z\" clip-rule=\"evenodd\" /></svg>`,\n success: `<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 16 16\" fill=\"currentColor\" aria-hidden=\"true\"><path fill-rule=\"evenodd\" d=\"M8 15A7 7 0 1 0 8 1a7 7 0 0 0 0 14Zm3.844-8.791a.75.75 0 0 0-1.188-.918l-3.7 4.79-1.649-1.833a.75.75 0 1 0-1.114 1.004l2.25 2.5a.75.75 0 0 0 1.151-.043l4.25-5.5Z\" clip-rule=\"evenodd\" /></svg>`,\n warning: `<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 16 16\" fill=\"currentColor\" aria-hidden=\"true\"><path fill-rule=\"evenodd\" d=\"M6.701 2.25c.577-1 2.02-1 2.598 0l5.196 9a1.5 1.5 0 0 1-1.299 2.25H2.804a1.5 1.5 0 0 1-1.3-2.25l5.197-9ZM8 4a.75.75 0 0 1 .75.75v3a.75.75 0 0 1-1.5 0v-3A.75.75 0 0 1 8 4Zm0 8a1 1 0 1 0 0-2 1 1 0 0 0 0 2Z\" clip-rule=\"evenodd\" /></svg>`,\n error: `<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 16 16\" fill=\"currentColor\" aria-hidden=\"true\"><path fill-rule=\"evenodd\" d=\"M8 15A7 7 0 1 0 8 1a7 7 0 0 0 0 14ZM8 4a.75.75 0 0 1 .75.75v3a.75.75 0 0 1-1.5 0v-3A.75.75 0 0 1 8 4Zm0 8a1 1 0 1 0 0-2 1 1 0 0 0 0 2Z\" clip-rule=\"evenodd\" /></svg>`,\n sync: `<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 16 16\" fill=\"currentColor\" aria-hidden=\"true\"><path fill-rule=\"evenodd\" d=\"M13.836 2.477a.75.75 0 0 1 .75.75v3.182a.75.75 0 0 1-.75.75h-3.182a.75.75 0 0 1 0-1.5h1.37l-.84-.841a4.5 4.5 0 0 0-7.08.681.75.75 0 0 1-1.264-.808 6 6 0 0 1 9.44-.908l.97.969V3.227a.75.75 0 0 1 .75-.75Zm-1.09 7.595a6 6 0 0 1-9.44.908l-.97-.969v1.637a.75.75 0 0 1-1.5 0V8.466a.75.75 0 0 1 .75-.75h3.182a.75.75 0 0 1 0 1.5h-1.37l.84.841a4.5 4.5 0 0 0 7.08-.681.75.75 0 0 1 1.264.808Z\" clip-rule=\"evenodd\" /></svg>`,\n}\n\nconst CLOSE_ICON = `<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 16 16\" fill=\"currentColor\" aria-hidden=\"true\"><path d=\"M5.28 4.22a.75.75 0 0 0-1.06 1.06L6.94 8l-2.72 2.72a.75.75 0 1 0 1.06 1.06L8 9.06l2.72 2.72a.75.75 0 1 0 1.06-1.06L9.06 8l2.72-2.72a.75.75 0 0 0-1.06-1.06L8 6.94 5.28 4.22Z\" /></svg>`\n\n// =============================================================================\n// NotificationBar Class\n// =============================================================================\n\n/**\n * 通知バーコンポーネント\n */\nexport class NotificationBar {\n private config: NotificationBarConfig\n private state: NotificationBarState\n private callbacks: NotificationBarCallbacks\n private container: HTMLElement\n private closeHandler: ((event: Event) => void) | null = null\n private actionHandler: ((event: Event) => void) | null = null\n\n constructor(\n container: HTMLElement,\n config: NotificationBarConfig,\n callbacks: NotificationBarCallbacks = {}\n ) {\n this.config = config\n this.container = container\n this.callbacks = callbacks\n this.state = this.createInitialState()\n }\n\n // ===========================================================================\n // Public Methods\n // ===========================================================================\n\n /**\n * 通知バーをレンダリング\n */\n render(): void {\n this.cleanup()\n this.container.innerHTML = ''\n\n const type = this.config.type ?? 'info'\n const bold = this.state.bold\n const closable = this.config.closable ?? true\n\n // コンテナのクラスとデータ属性を設定\n this.container.className = [\n 'mokkun-notification-bar',\n `notification-bar-${type}`,\n bold ? 'notification-bar-bold' : '',\n !this.state.visible ? 'notification-bar-hidden' : '',\n ].filter(Boolean).join(' ')\n\n this.container.setAttribute('data-type', type)\n if (bold) {\n this.container.setAttribute('data-bold', '')\n } else {\n this.container.removeAttribute('data-bold')\n }\n\n if (!this.state.visible) {\n this.container.setAttribute('data-hidden', '')\n return\n } else {\n this.container.removeAttribute('data-hidden')\n }\n\n // ARIA属性\n const role = this.config.role ?? 'status'\n this.container.setAttribute('role', role)\n this.container.setAttribute('aria-live', role === 'alert' ? 'assertive' : 'polite')\n\n const ariaLabel = this.config.ariaLabel ?? this.state.message\n this.container.setAttribute('aria-label', ariaLabel)\n\n // 通知バーの内容を作成\n const content = this.renderContent()\n this.container.appendChild(content)\n\n // アクションボタン\n if (this.config.actionLabel && this.callbacks.onAction) {\n const actionButton = this.renderActionButton()\n this.container.appendChild(actionButton)\n }\n\n // 閉じるボタン\n if (closable && this.callbacks.onClose) {\n const closeButton = this.renderCloseButton()\n this.container.appendChild(closeButton)\n }\n }\n\n /**\n * メッセージを設定\n */\n setMessage(message: string): void {\n if (this.state.message === message) {\n return\n }\n\n this.state = {\n ...this.state,\n message,\n }\n\n this.render()\n }\n\n /**\n * 表示状態を設定\n */\n setVisible(visible: boolean): void {\n if (this.state.visible === visible) {\n return\n }\n\n this.state = {\n ...this.state,\n visible,\n }\n\n this.render()\n }\n\n /**\n * 強調表示を設定\n */\n setBold(bold: boolean): void {\n if (this.state.bold === bold) {\n return\n }\n\n this.state = {\n ...this.state,\n bold,\n }\n\n this.render()\n }\n\n /**\n * 通知を表示\n */\n show(): void {\n this.setVisible(true)\n }\n\n /**\n * 通知を非表示\n */\n hide(): void {\n this.setVisible(false)\n }\n\n /**\n * 現在のメッセージを取得\n */\n getMessage(): string {\n return this.state.message\n }\n\n /**\n * 表示状態を取得\n */\n isVisible(): boolean {\n return this.state.visible\n }\n\n /**\n * 強調表示状態を取得\n */\n isBold(): boolean {\n return this.state.bold\n }\n\n /**\n * 現在の状態を取得\n */\n getState(): Readonly<NotificationBarState> {\n return { ...this.state }\n }\n\n /**\n * コンポーネントを破棄\n */\n destroy(): void {\n this.cleanup()\n this.container.innerHTML = ''\n this.container.className = ''\n this.container.removeAttribute('role')\n this.container.removeAttribute('aria-live')\n this.container.removeAttribute('aria-label')\n this.container.removeAttribute('data-type')\n this.container.removeAttribute('data-bold')\n this.container.removeAttribute('data-hidden')\n }\n\n // ===========================================================================\n // Private Methods\n // ===========================================================================\n\n /**\n * 初期状態を作成\n */\n private createInitialState(): NotificationBarState {\n return {\n message: this.config.message,\n visible: true,\n bold: this.config.bold ?? false,\n }\n }\n\n /**\n * 通知バーの内容をレンダリング\n */\n private renderContent(): HTMLElement {\n const content = createElement('div', {\n className: 'notification-bar-content',\n })\n\n // アイコン\n const type = this.config.type ?? 'info'\n const iconEl = createElement('span', {\n className: 'notification-bar-icon',\n attributes: {\n 'aria-hidden': 'true',\n },\n })\n iconEl.innerHTML = BUILTIN_ICONS[type]\n content.appendChild(iconEl)\n\n // メッセージ\n const messageEl = createElement('span', {\n className: 'notification-bar-message',\n textContent: this.state.message,\n })\n content.appendChild(messageEl)\n\n return content\n }\n\n /**\n * アクションボタンをレンダリング\n */\n private renderActionButton(): HTMLElement {\n const button = createElement('button', {\n className: 'notification-bar-action',\n textContent: this.config.actionLabel,\n attributes: {\n type: 'button',\n },\n })\n\n this.actionHandler = this.handleAction.bind(this)\n button.addEventListener('click', this.actionHandler)\n\n return button\n }\n\n /**\n * 閉じるボタンをレンダリング\n */\n private renderCloseButton(): HTMLElement {\n const button = createElement('button', {\n className: 'notification-bar-close',\n attributes: {\n type: 'button',\n 'aria-label': '閉じる',\n },\n })\n button.innerHTML = CLOSE_ICON\n\n this.closeHandler = this.handleClose.bind(this)\n button.addEventListener('click', this.closeHandler)\n\n return button\n }\n\n /**\n * アクションボタンクリックハンドラー\n */\n private handleAction(event: Event): void {\n event.stopPropagation()\n this.callbacks.onAction?.()\n }\n\n /**\n * 閉じるボタンクリックハンドラー\n */\n private handleClose(event: Event): void {\n event.stopPropagation()\n this.callbacks.onClose?.()\n }\n\n /**\n * イベントリスナーをクリーンアップ\n */\n private cleanup(): void {\n if (this.closeHandler) {\n const closeButton = this.container.querySelector('.notification-bar-close')\n closeButton?.removeEventListener('click', this.closeHandler)\n this.closeHandler = null\n }\n if (this.actionHandler) {\n const actionButton = this.container.querySelector('.notification-bar-action')\n actionButton?.removeEventListener('click', this.actionHandler)\n this.actionHandler = null\n }\n }\n\n // ===========================================================================\n // Static Field Renderer\n // ===========================================================================\n\n static renderField(field: InputField): string {\n const notificationField = field as InputField & {\n variant?: 'info' | 'success' | 'warning' | 'error'\n dismissible?: boolean\n }\n const variant = notificationField.variant ?? 'info'\n const dismissible = notificationField.dismissible ?? true\n\n const iconMap: Record<string, string> = {\n info: 'ℹ️',\n success: '✓',\n warning: '⚠️',\n error: '✕',\n }\n\n const notificationHtml = `\n <div class=\"mokkun-notification-bar notification-${variant}\" role=\"alert\">\n <span class=\"notification-icon\">${iconMap[variant]}</span>\n <div class=\"notification-content\">\n <span class=\"notification-message\">${escapeHtml(field.description ?? field.label)}</span>\n </div>\n ${dismissible ? '<button type=\"button\" class=\"notification-dismiss\" aria-label=\"閉じる\">×</button>' : ''}\n </div>\n `\n return createFieldWrapper(field, notificationHtml)\n }\n}\n\n// =============================================================================\n// NotificationBarStack Class\n// =============================================================================\n\n/**\n * 通知アイテム\n */\nexport interface NotificationItem {\n /** 通知ID */\n id: string\n /** メッセージ */\n message: string\n /** タイプ */\n type?: NotificationBarType\n /** アクションラベル */\n actionLabel?: string\n /** 強調表示 */\n bold?: boolean\n /** アクセシビリティ用のロール */\n role?: 'alert' | 'status'\n /** アクションコールバック */\n onAction?: () => void\n}\n\n/**\n * 通知スタックの状態\n */\nexport interface NotificationBarStackState {\n /** 通知一覧 */\n notifications: NotificationItem[]\n}\n\n/**\n * 通知スタックのコールバック\n */\nexport interface NotificationBarStackCallbacks {\n /** 通知が閉じられた時 */\n onNotificationClose?: (id: string) => void\n /** 全通知が閉じられた時 */\n onAllClosed?: () => void\n}\n\n/**\n * 通知スタックの設定\n */\nexport interface NotificationBarStackConfig {\n /** 初期通知リスト */\n notifications?: NotificationItem[]\n /** 最大表示数 */\n maxVisible?: number\n}\n\n/**\n * 通知スタックコンポーネント\n * 複数の通知をスタック表示する\n */\nexport class NotificationBarStack {\n private config: NotificationBarStackConfig\n private state: NotificationBarStackState\n private callbacks: NotificationBarStackCallbacks\n private container: HTMLElement\n private notificationBars: Map<string, NotificationBar> = new Map()\n\n constructor(\n container: HTMLElement,\n config: NotificationBarStackConfig = {},\n callbacks: NotificationBarStackCallbacks = {}\n ) {\n this.config = config\n this.container = container\n this.callbacks = callbacks\n this.state = this.createInitialState()\n }\n\n // ===========================================================================\n // Public Methods\n // ===========================================================================\n\n /**\n * スタックをレンダリング\n */\n render(): void {\n this.container.innerHTML = ''\n this.notificationBars.clear()\n\n this.container.className = 'mokkun-notification-bar-stack'\n\n const maxVisible = this.config.maxVisible ?? 5\n const visibleNotifications = this.state.notifications.slice(0, maxVisible)\n\n visibleNotifications.forEach((notification) => {\n const wrapper = createElement('div', {\n className: 'notification-bar-wrapper',\n attributes: {\n 'data-notification-id': notification.id,\n },\n })\n\n const notificationContainer = createElement('div', {})\n wrapper.appendChild(notificationContainer)\n\n const notificationBar = new NotificationBar(\n notificationContainer,\n {\n message: notification.message,\n type: notification.type,\n actionLabel: notification.actionLabel,\n closable: true,\n bold: notification.bold,\n role: notification.role,\n },\n {\n onClose: () => this.removeNotification(notification.id),\n onAction: notification.onAction,\n }\n )\n\n notificationBar.render()\n this.notificationBars.set(notification.id, notificationBar)\n this.container.appendChild(wrapper)\n })\n }\n\n /**\n * 通知を追加\n */\n addNotification(notification: Omit<NotificationItem, 'id'> & { id?: string }): string {\n const id = notification.id ?? generateId('notification')\n const newNotification: NotificationItem = {\n ...notification,\n id,\n }\n\n this.state = {\n ...this.state,\n notifications: [newNotification, ...this.state.notifications],\n }\n\n this.render()\n return id\n }\n\n /**\n * 通知を削除\n */\n removeNotification(id: string): void {\n const notification = this.state.notifications.find((n) => n.id === id)\n if (!notification) {\n return\n }\n\n const notificationBar = this.notificationBars.get(id)\n if (notificationBar) {\n notificationBar.destroy()\n this.notificationBars.delete(id)\n }\n\n this.state = {\n ...this.state,\n notifications: this.state.notifications.filter((n) => n.id !== id),\n }\n\n this.callbacks.onNotificationClose?.(id)\n\n if (this.state.notifications.length === 0) {\n this.callbacks.onAllClosed?.()\n }\n\n this.render()\n }\n\n /**\n * 全通知をクリア\n */\n clearAll(): void {\n this.notificationBars.forEach((bar) => bar.destroy())\n this.notificationBars.clear()\n\n this.state = {\n ...this.state,\n notifications: [],\n }\n\n this.callbacks.onAllClosed?.()\n this.render()\n }\n\n /**\n * 通知数を取得\n */\n getCount(): number {\n return this.state.notifications.length\n }\n\n /**\n * 通知一覧を取得\n */\n getNotifications(): Readonly<NotificationItem[]> {\n return [...this.state.notifications]\n }\n\n /**\n * 現在の状態を取得\n */\n getState(): Readonly<NotificationBarStackState> {\n return {\n notifications: [...this.state.notifications],\n }\n }\n\n /**\n * コンポーネントを破棄\n */\n destroy(): void {\n this.notificationBars.forEach((bar) => bar.destroy())\n this.notificationBars.clear()\n this.container.innerHTML = ''\n this.container.className = ''\n }\n\n // ===========================================================================\n // Private Methods\n // ===========================================================================\n\n /**\n * 初期状態を作成\n */\n private createInitialState(): NotificationBarStackState {\n return {\n notifications: this.config.notifications ? [...this.config.notifications] : [],\n }\n }\n}\n\n// =============================================================================\n// Factory Functions\n// =============================================================================\n\n/**\n * 通知バーを作成\n */\nexport function createNotificationBar(\n container: HTMLElement,\n config: NotificationBarConfig,\n callbacks: NotificationBarCallbacks = {}\n): NotificationBar {\n const notificationBar = new NotificationBar(container, config, callbacks)\n notificationBar.render()\n return notificationBar\n}\n\n/**\n * 通知スタックを作成\n */\nexport function createNotificationBarStack(\n container: HTMLElement,\n config: NotificationBarStackConfig = {},\n callbacks: NotificationBarStackCallbacks = {}\n): NotificationBarStack {\n const stack = new NotificationBarStack(container, config, callbacks)\n stack.render()\n return stack\n}\n","/**\n * ResponseMessage Component\n * レスポンスメッセージコンポーネント\n *\n * \n * https://smarthr.design/products/components/response-message/\n *\n * 機能:\n * - タイプ(success/error/warning/info)\n * - 詳細表示(折りたたみ)\n * - 再試行ボタン\n * - アイコン表示\n *\n * 用途:\n * - フォーム送信結果\n * - API呼び出し結果\n * - バリデーションエラー表示\n */\n\nimport { createElement, generateId } from '../utils/dom'\nimport { escapeHtml, createFieldWrapper } from '../utils/field-helpers'\nimport type { InputField } from '../../types/schema'\n\n// =============================================================================\n// Types\n// =============================================================================\n\n/**\n * レスポンスメッセージのタイプ\n * - success: 成功・完了\n * - error: エラー・失敗\n * - warning: 警告\n * - info: 情報\n */\nexport type ResponseMessageType = 'success' | 'error' | 'warning' | 'info'\n\n/**\n * レスポンスメッセージの状態\n */\nexport interface ResponseMessageState {\n /** 表示中かどうか */\n visible: boolean\n /** 詳細展開状態 */\n detailsExpanded: boolean\n /** ローディング状態(再試行中) */\n loading: boolean\n}\n\n/**\n * レスポンスメッセージのコールバック\n */\nexport interface ResponseMessageCallbacks {\n /** 再試行ボタンクリック時 */\n onRetry?: () => void | Promise<void>\n /** 詳細展開時 */\n onExpandDetails?: () => void\n /** 詳細折りたたみ時 */\n onCollapseDetails?: () => void\n /** 閉じるボタンクリック時 */\n onClose?: () => void\n}\n\n/**\n * レスポンスメッセージの設定\n */\nexport interface ResponseMessageConfig {\n /** メインメッセージ */\n message: string\n /** メッセージタイプ */\n type?: ResponseMessageType\n /** 詳細メッセージ(折りたたみ表示) */\n details?: string | string[]\n /** 再試行ボタンを表示 */\n showRetry?: boolean\n /** 再試行ボタンのラベル */\n retryLabel?: string\n /** 閉じるボタンを表示 */\n showClose?: boolean\n /** アイコンを非表示にする */\n hideIcon?: boolean\n /** カスタムアイコン(SVG文字列) */\n icon?: string\n /** 詳細セクションのラベル */\n detailsLabel?: string\n /** ID属性 */\n id?: string\n /** カスタムCSSクラス */\n className?: string\n /** アクセシビリティ用ラベル */\n ariaLabel?: string\n}\n\n// =============================================================================\n// Built-in Icons\n// =============================================================================\n\nconst ICONS: Record<ResponseMessageType, string> = {\n success: `<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"20\" height=\"20\" viewBox=\"0 0 20 20\" fill=\"currentColor\" aria-hidden=\"true\"><path fill-rule=\"evenodd\" d=\"M10 18a8 8 0 100-16 8 8 0 000 16zm3.857-9.809a.75.75 0 00-1.214-.882l-3.483 4.79-1.88-1.88a.75.75 0 10-1.06 1.061l2.5 2.5a.75.75 0 001.137-.089l4-5.5z\" clip-rule=\"evenodd\" /></svg>`,\n error: `<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"20\" height=\"20\" viewBox=\"0 0 20 20\" fill=\"currentColor\" aria-hidden=\"true\"><path fill-rule=\"evenodd\" d=\"M18 10a8 8 0 11-16 0 8 8 0 0116 0zm-8-5a.75.75 0 01.75.75v4.5a.75.75 0 01-1.5 0v-4.5A.75.75 0 0110 5zm0 10a1 1 0 100-2 1 1 0 000 2z\" clip-rule=\"evenodd\" /></svg>`,\n warning: `<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"20\" height=\"20\" viewBox=\"0 0 20 20\" fill=\"currentColor\" aria-hidden=\"true\"><path fill-rule=\"evenodd\" d=\"M8.485 2.495c.673-1.167 2.357-1.167 3.03 0l6.28 10.875c.673 1.167-.17 2.625-1.516 2.625H3.72c-1.347 0-2.189-1.458-1.515-2.625L8.485 2.495zM10 5a.75.75 0 01.75.75v3.5a.75.75 0 01-1.5 0v-3.5A.75.75 0 0110 5zm0 9a1 1 0 100-2 1 1 0 000 2z\" clip-rule=\"evenodd\" /></svg>`,\n info: `<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"20\" height=\"20\" viewBox=\"0 0 20 20\" fill=\"currentColor\" aria-hidden=\"true\"><path fill-rule=\"evenodd\" d=\"M18 10a8 8 0 11-16 0 8 8 0 0116 0zm-7-4a1 1 0 11-2 0 1 1 0 012 0zM9 9a.75.75 0 000 1.5h.253a.25.25 0 01.244.304l-.459 2.066A1.75 1.75 0 0010.747 15H11a.75.75 0 000-1.5h-.253a.25.25 0 01-.244-.304l.459-2.066A1.75 1.75 0 009.253 9H9z\" clip-rule=\"evenodd\" /></svg>`,\n}\n\nconst CHEVRON_DOWN = `<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"currentColor\" aria-hidden=\"true\"><path fill-rule=\"evenodd\" d=\"M4.22 6.22a.75.75 0 011.06 0L8 8.94l2.72-2.72a.75.75 0 111.06 1.06l-3.25 3.25a.75.75 0 01-1.06 0L4.22 7.28a.75.75 0 010-1.06z\" clip-rule=\"evenodd\" /></svg>`\n\nconst CLOSE_ICON = `<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"currentColor\" aria-hidden=\"true\"><path d=\"M3.72 3.72a.75.75 0 011.06 0L8 6.94l3.22-3.22a.75.75 0 111.06 1.06L9.06 8l3.22 3.22a.75.75 0 11-1.06 1.06L8 9.06l-3.22 3.22a.75.75 0 01-1.06-1.06L6.94 8 3.72 4.78a.75.75 0 010-1.06z\" /></svg>`\n\nconst RETRY_ICON = `<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"currentColor\" aria-hidden=\"true\"><path fill-rule=\"evenodd\" d=\"M8 3a5 5 0 104.546 2.914.75.75 0 011.364-.628A6.5 6.5 0 118 1.5v-.75a.75.75 0 011.28-.53l2 2a.75.75 0 010 1.06l-2 2a.75.75 0 01-1.28-.53V3z\" clip-rule=\"evenodd\" /></svg>`\n\nconst LOADING_ICON = `<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"currentColor\" aria-hidden=\"true\" class=\"response-message-spinner\"><circle cx=\"8\" cy=\"8\" r=\"6\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" opacity=\"0.25\" /><path d=\"M14 8a6 6 0 00-6-6\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" /></svg>`\n\n/** アニメーション時間(ミリ秒) */\nconst ANIMATION_DURATION_MS = 200\n\n// =============================================================================\n// ResponseMessage Class\n// =============================================================================\n\n/**\n * レスポンスメッセージコンポーネント\n */\nexport class ResponseMessage {\n private config: ResponseMessageConfig\n private state: ResponseMessageState\n private callbacks: ResponseMessageCallbacks\n private container: HTMLElement\n private instanceId: string\n private detailsId: string\n private detailsToggleHandler: (() => void) | null = null\n private retryHandler: (() => Promise<void>) | null = null\n private closeHandler: (() => void) | null = null\n\n constructor(\n container: HTMLElement,\n config: ResponseMessageConfig,\n callbacks: ResponseMessageCallbacks = {}\n ) {\n this.config = config\n this.container = container\n this.callbacks = callbacks\n this.instanceId = config.id ?? generateId('response-message')\n this.detailsId = `${this.instanceId}-details`\n this.state = this.createInitialState()\n }\n\n // ===========================================================================\n // Public Methods\n // ===========================================================================\n\n /**\n * コンポーネントをレンダリング\n */\n render(): void {\n // イベントリスナーをクリーンアップ\n this.cleanupEventListeners()\n this.container.innerHTML = ''\n\n if (!this.state.visible) {\n this.container.style.display = 'none'\n return\n }\n\n this.container.style.display = ''\n\n const type = this.config.type ?? 'info'\n\n this.container.className = this.buildClassName(type)\n this.container.id = this.instanceId\n this.container.setAttribute('role', type === 'error' ? 'alert' : 'status')\n this.container.setAttribute('aria-live', type === 'error' ? 'assertive' : 'polite')\n\n if (this.config.ariaLabel) {\n this.container.setAttribute('aria-label', this.config.ariaLabel)\n }\n\n // アイコン\n if (!this.config.hideIcon) {\n const iconEl = this.renderIcon(type)\n this.container.appendChild(iconEl)\n }\n\n // コンテンツ領域\n const contentEl = this.renderContent()\n this.container.appendChild(contentEl)\n\n // 閉じるボタン\n if (this.config.showClose) {\n const closeEl = this.renderCloseButton()\n this.container.appendChild(closeEl)\n }\n }\n\n /**\n * メッセージを表示\n */\n show(): void {\n if (this.state.visible) {\n return\n }\n\n this.state = {\n ...this.state,\n visible: true,\n }\n\n this.render()\n }\n\n /**\n * メッセージを非表示\n */\n hide(): void {\n if (!this.state.visible) {\n return\n }\n\n this.state = {\n ...this.state,\n visible: false,\n }\n\n this.render()\n this.callbacks.onClose?.()\n }\n\n /**\n * 詳細を展開\n */\n expandDetails(): void {\n if (this.state.detailsExpanded || !this.hasDetails()) {\n return\n }\n\n this.state = {\n ...this.state,\n detailsExpanded: true,\n }\n\n this.updateDetailsState()\n this.callbacks.onExpandDetails?.()\n }\n\n /**\n * 詳細を折りたたむ\n */\n collapseDetails(): void {\n if (!this.state.detailsExpanded) {\n return\n }\n\n this.state = {\n ...this.state,\n detailsExpanded: false,\n }\n\n this.updateDetailsState()\n this.callbacks.onCollapseDetails?.()\n }\n\n /**\n * 詳細の展開/折りたたみを切り替え\n */\n toggleDetails(): void {\n if (this.state.detailsExpanded) {\n this.collapseDetails()\n } else {\n this.expandDetails()\n }\n }\n\n /**\n * ローディング状態を設定\n */\n setLoading(loading: boolean): void {\n if (this.state.loading === loading) {\n return\n }\n\n this.state = {\n ...this.state,\n loading,\n }\n\n this.updateRetryButtonState()\n }\n\n /**\n * メッセージを更新\n */\n setMessage(message: string): void {\n this.config = {\n ...this.config,\n message,\n }\n this.render()\n }\n\n /**\n * 詳細を更新\n */\n setDetails(details: string | string[] | undefined): void {\n this.config = {\n ...this.config,\n details,\n }\n this.render()\n }\n\n /**\n * タイプを更新\n */\n setType(type: ResponseMessageType): void {\n this.config = {\n ...this.config,\n type,\n }\n this.render()\n }\n\n /**\n * 設定を更新\n */\n update(config: Partial<ResponseMessageConfig>): void {\n this.config = {\n ...this.config,\n ...config,\n }\n this.render()\n }\n\n /**\n * 現在の状態を取得\n */\n getState(): ResponseMessageState {\n return { ...this.state }\n }\n\n /**\n * 表示中かどうかを取得\n */\n isVisible(): boolean {\n return this.state.visible\n }\n\n /**\n * 詳細が展開中かどうかを取得\n */\n isDetailsExpanded(): boolean {\n return this.state.detailsExpanded\n }\n\n /**\n * コンポーネントを破棄\n */\n destroy(): void {\n this.cleanupEventListeners()\n this.container.innerHTML = ''\n this.container.removeAttribute('role')\n this.container.removeAttribute('aria-live')\n this.container.removeAttribute('aria-label')\n }\n\n // ===========================================================================\n // Private Methods - Initialization\n // ===========================================================================\n\n private createInitialState(): ResponseMessageState {\n return {\n visible: true,\n detailsExpanded: false,\n loading: false,\n }\n }\n\n /**\n * イベントリスナーをクリーンアップ\n */\n private cleanupEventListeners(): void {\n const toggleBtn = this.container.querySelector('.response-message-details-toggle')\n const retryBtn = this.container.querySelector('.response-message-retry')\n const closeBtn = this.container.querySelector('.response-message-close')\n\n if (toggleBtn && this.detailsToggleHandler) {\n toggleBtn.removeEventListener('click', this.detailsToggleHandler)\n }\n if (retryBtn && this.retryHandler) {\n retryBtn.removeEventListener('click', this.retryHandler)\n }\n if (closeBtn && this.closeHandler) {\n closeBtn.removeEventListener('click', this.closeHandler)\n }\n\n this.detailsToggleHandler = null\n this.retryHandler = null\n this.closeHandler = null\n }\n\n // ===========================================================================\n // Private Methods - Rendering\n // ===========================================================================\n\n private buildClassName(type: ResponseMessageType): string {\n const classNames = [\n 'mokkun-response-message',\n `response-message-${type}`,\n ]\n\n if (this.config.className) {\n classNames.push(this.config.className)\n }\n\n return classNames.join(' ')\n }\n\n private renderIcon(type: ResponseMessageType): HTMLElement {\n const iconEl = createElement('div', {\n className: 'response-message-icon',\n attributes: {\n 'aria-hidden': 'true',\n },\n })\n\n if (this.config.icon) {\n iconEl.innerHTML = this.sanitizeSvgIcon(this.config.icon) ?? ICONS[type]\n } else {\n iconEl.innerHTML = ICONS[type]\n }\n\n return iconEl\n }\n\n private renderContent(): HTMLElement {\n const contentEl = createElement('div', {\n className: 'response-message-content',\n })\n\n // メインメッセージ\n const messageEl = createElement('div', {\n className: 'response-message-text',\n textContent: this.config.message,\n })\n contentEl.appendChild(messageEl)\n\n // アクション領域(詳細トグル、再試行ボタン)\n const hasActions = this.hasDetails() || this.config.showRetry\n if (hasActions) {\n const actionsEl = this.renderActions()\n contentEl.appendChild(actionsEl)\n }\n\n // 詳細セクション\n if (this.hasDetails()) {\n const detailsEl = this.renderDetails()\n contentEl.appendChild(detailsEl)\n }\n\n return contentEl\n }\n\n private renderActions(): HTMLElement {\n const actionsEl = createElement('div', {\n className: 'response-message-actions',\n })\n\n // 詳細トグルボタン\n if (this.hasDetails()) {\n const toggleBtn = this.renderDetailsToggle()\n actionsEl.appendChild(toggleBtn)\n }\n\n // 再試行ボタン\n if (this.config.showRetry) {\n const retryBtn = this.renderRetryButton()\n actionsEl.appendChild(retryBtn)\n }\n\n return actionsEl\n }\n\n private renderDetailsToggle(): HTMLElement {\n const label = this.config.detailsLabel ?? '詳細'\n\n const toggleBtn = createElement('button', {\n className: `response-message-details-toggle${this.state.detailsExpanded ? ' is-expanded' : ''}`,\n attributes: {\n type: 'button',\n 'aria-expanded': String(this.state.detailsExpanded),\n 'aria-controls': this.detailsId,\n },\n })\n\n const labelSpan = createElement('span', {\n className: 'response-message-details-label',\n textContent: label,\n })\n toggleBtn.appendChild(labelSpan)\n\n const chevronSpan = createElement('span', {\n className: 'response-message-details-chevron',\n })\n chevronSpan.innerHTML = CHEVRON_DOWN\n toggleBtn.appendChild(chevronSpan)\n\n this.detailsToggleHandler = () => {\n this.toggleDetails()\n }\n toggleBtn.addEventListener('click', this.detailsToggleHandler)\n\n return toggleBtn\n }\n\n private renderRetryButton(): HTMLElement {\n const label = this.config.retryLabel ?? '再試行'\n\n const retryBtn = createElement('button', {\n className: `response-message-retry${this.state.loading ? ' is-loading' : ''}`,\n attributes: {\n type: 'button',\n 'aria-disabled': String(this.state.loading),\n },\n })\n\n if (this.state.loading) {\n retryBtn.disabled = true\n }\n\n const iconSpan = createElement('span', {\n className: 'response-message-retry-icon',\n })\n iconSpan.innerHTML = this.state.loading ? LOADING_ICON : RETRY_ICON\n retryBtn.appendChild(iconSpan)\n\n const labelSpan = createElement('span', {\n className: 'response-message-retry-label',\n textContent: label,\n })\n retryBtn.appendChild(labelSpan)\n\n this.retryHandler = async () => {\n if (this.state.loading) {\n return\n }\n\n const retryFn = this.callbacks.onRetry\n if (!retryFn) {\n return\n }\n\n this.setLoading(true)\n\n try {\n await retryFn()\n } finally {\n this.setLoading(false)\n }\n }\n retryBtn.addEventListener('click', this.retryHandler)\n\n return retryBtn\n }\n\n private renderDetails(): HTMLElement {\n const detailsWrapper = createElement('div', {\n className: `response-message-details-wrapper${this.state.detailsExpanded ? ' is-expanded' : ''}`,\n })\n\n const detailsEl = createElement('div', {\n className: 'response-message-details',\n attributes: {\n id: this.detailsId,\n },\n })\n\n if (!this.state.detailsExpanded) {\n detailsEl.setAttribute('hidden', '')\n }\n\n // 詳細コンテンツ\n const details = this.config.details\n if (Array.isArray(details)) {\n const listEl = createElement('ul', {\n className: 'response-message-details-list',\n })\n details.forEach((item) => {\n const li = createElement('li', {\n textContent: item,\n })\n listEl.appendChild(li)\n })\n detailsEl.appendChild(listEl)\n } else if (details) {\n const textEl = createElement('div', {\n className: 'response-message-details-text',\n textContent: details,\n })\n detailsEl.appendChild(textEl)\n }\n\n detailsWrapper.appendChild(detailsEl)\n\n return detailsWrapper\n }\n\n private renderCloseButton(): HTMLElement {\n const closeBtn = createElement('button', {\n className: 'response-message-close',\n attributes: {\n type: 'button',\n 'aria-label': '閉じる',\n },\n })\n\n closeBtn.innerHTML = CLOSE_ICON\n\n this.closeHandler = () => {\n this.hide()\n }\n closeBtn.addEventListener('click', this.closeHandler)\n\n return closeBtn\n }\n\n // ===========================================================================\n // Private Methods - State Updates\n // ===========================================================================\n\n private updateDetailsState(): void {\n const toggle = this.container.querySelector('.response-message-details-toggle')\n const wrapper = this.container.querySelector('.response-message-details-wrapper')\n const details = this.container.querySelector('.response-message-details')\n\n if (toggle) {\n toggle.setAttribute('aria-expanded', String(this.state.detailsExpanded))\n if (this.state.detailsExpanded) {\n toggle.classList.add('is-expanded')\n } else {\n toggle.classList.remove('is-expanded')\n }\n }\n\n if (wrapper) {\n if (this.state.detailsExpanded) {\n wrapper.classList.add('is-expanded')\n } else {\n wrapper.classList.remove('is-expanded')\n }\n }\n\n if (details) {\n if (this.state.detailsExpanded) {\n details.removeAttribute('hidden')\n } else {\n // アニメーション終了後にhiddenを設定\n setTimeout(() => {\n if (!this.state.detailsExpanded) {\n details.setAttribute('hidden', '')\n }\n }, ANIMATION_DURATION_MS)\n }\n }\n }\n\n private updateRetryButtonState(): void {\n const retryBtn = this.container.querySelector('.response-message-retry') as HTMLButtonElement\n const iconSpan = this.container.querySelector('.response-message-retry-icon')\n\n if (retryBtn) {\n retryBtn.disabled = this.state.loading\n retryBtn.setAttribute('aria-disabled', String(this.state.loading))\n\n if (this.state.loading) {\n retryBtn.classList.add('is-loading')\n } else {\n retryBtn.classList.remove('is-loading')\n }\n }\n\n if (iconSpan) {\n iconSpan.innerHTML = this.state.loading ? LOADING_ICON : RETRY_ICON\n }\n }\n\n // ===========================================================================\n // Private Methods - Utilities\n // ===========================================================================\n\n private hasDetails(): boolean {\n const details = this.config.details\n if (Array.isArray(details)) {\n return details.length > 0\n }\n return Boolean(details)\n }\n\n /**\n * カスタムSVGアイコンをサニタイズ\n */\n private sanitizeSvgIcon(input: string): string | null {\n const trimmed = input.trim()\n\n if (!trimmed.toLowerCase().startsWith('<svg') || !trimmed.toLowerCase().endsWith('</svg>')) {\n return null\n }\n\n const parser = new DOMParser()\n const doc = parser.parseFromString(trimmed, 'image/svg+xml')\n\n const parserError = doc.querySelector('parsererror')\n if (parserError) {\n return null\n }\n\n const svg = doc.querySelector('svg')\n if (!svg) {\n return null\n }\n\n // 危険な要素を削除\n const dangerousElements = ['script', 'foreignObject', 'iframe', 'object', 'embed', 'use']\n dangerousElements.forEach((tag) => {\n svg.querySelectorAll(tag).forEach((el) => el.remove())\n })\n\n // 危険な属性を削除\n const dangerousAttrs = [\n 'onload', 'onerror', 'onclick', 'onmouseover', 'onmouseout', 'onmousedown',\n 'onmouseup', 'onfocus', 'onblur', 'onkeydown', 'onkeyup', 'onkeypress',\n 'onsubmit', 'onreset', 'onchange', 'oninput', 'onscroll', 'onresize',\n 'onanimationstart', 'onanimationend', 'ontransitionend',\n ]\n\n dangerousAttrs.forEach((attr) => svg.removeAttribute(attr))\n const svgHref = svg.getAttribute('href') ?? svg.getAttribute('xlink:href')\n if (svgHref && svgHref.toLowerCase().startsWith('javascript:')) {\n svg.removeAttribute('href')\n svg.removeAttribute('xlink:href')\n }\n\n svg.querySelectorAll('*').forEach((el) => {\n dangerousAttrs.forEach((attr) => el.removeAttribute(attr))\n const href = el.getAttribute('href') ?? el.getAttribute('xlink:href')\n if (href && href.toLowerCase().startsWith('javascript:')) {\n el.removeAttribute('href')\n el.removeAttribute('xlink:href')\n }\n })\n\n return svg.outerHTML\n }\n\n // ===========================================================================\n // Static Field Renderer\n // ===========================================================================\n\n static renderField(field: InputField): string {\n const messageField = field as InputField & {\n variant?: 'success' | 'error' | 'warning' | 'info'\n }\n const variant = messageField.variant ?? 'success'\n\n const iconMap: Record<string, string> = {\n success: '✓',\n error: '✕',\n warning: '⚠',\n info: 'ℹ',\n }\n\n const messageHtml = `\n <div class=\"mokkun-response-message response-${variant}\" role=\"status\">\n <span class=\"response-icon\">${iconMap[variant]}</span>\n <span class=\"response-text\">${escapeHtml(field.description ?? field.label)}</span>\n </div>\n `\n return createFieldWrapper(field, messageHtml)\n }\n}\n\n// =============================================================================\n// Factory Function\n// =============================================================================\n\n/**\n * レスポンスメッセージを作成\n */\nexport function createResponseMessage(\n container: HTMLElement,\n config: ResponseMessageConfig,\n callbacks: ResponseMessageCallbacks = {}\n): ResponseMessage {\n const responseMessage = new ResponseMessage(container, config, callbacks)\n responseMessage.render()\n return responseMessage\n}\n","/**\n * Timeline Component\n * タイムラインコンポーネント\n *\n * \n * - 日時表示(datetime / dateLabel)\n * - 時間フォーマット(none / HH:mm:ss / HH:mm)\n * - アイコンカスタマイズ\n * - コンテンツのカスタマイズ\n * - 接続線のスタイル\n * - 現在のアイテム強調(current)\n *\n * @see https://smarthr.design/products/components/timeline/\n */\n\nimport { createElement, clearElement } from '../utils/dom'\nimport { createFieldWrapper } from '../utils/field-helpers'\nimport type { InputField } from '../../types/schema'\n\n// =============================================================================\n// Types\n// =============================================================================\n\n/**\n * 時間表示フォーマット\n * - none: 時間を表示しない\n * - HH:mm:ss: 時:分:秒\n * - HH:mm: 時:分\n */\nexport type TimelineTimeFormat = 'none' | 'HH:mm:ss' | 'HH:mm'\n\n/**\n * ビルトインアイコンタイプ\n */\nexport type TimelineIconType =\n | 'circle'\n | 'dot'\n | 'check'\n | 'warning'\n | 'error'\n | 'info'\n | 'clock'\n | 'star'\n | 'user'\n | 'message'\n\n/**\n * タイムラインアイテムの設定\n */\nexport interface TimelineItemConfig {\n /** 日時(Date or ISO string) */\n datetime: string | Date\n /** カスタム日付ラベル(表示用、datetimeの代わりに表示) */\n dateLabel?: string\n /** 時間表示フォーマット */\n timeFormat?: TimelineTimeFormat\n /** 日付サフィックスエリア(日付の後に表示される追加コンテンツ) */\n dateSuffixArea?: string\n /** サイドアクションエリア(右側に表示されるアクションボタン等) */\n sideActionArea?: string\n /** 現在のアイテム(強調表示) */\n current?: boolean\n /** アイコン(ビルトインタイプまたはカスタムSVG) */\n icon?: TimelineIconType | string\n /** アイコンの色(CSS color値) */\n iconColor?: string\n /** コンテンツ(HTML文字列) */\n content: string\n /** タイトル */\n title?: string\n}\n\n/**\n * タイムラインの設定\n */\nexport interface TimelineConfig {\n /** タイムラインアイテム配列 */\n items: TimelineItemConfig[]\n}\n\n/**\n * タイムラインの状態\n */\nexport interface TimelineState {\n /** アイテム数 */\n itemCount: number\n /** 現在のアイテムインデックス(-1 = なし) */\n currentIndex: number\n}\n\n/**\n * タイムラインのコールバック\n */\nexport interface TimelineCallbacks {\n /** アイテムクリック時 */\n onItemClick?: (index: number, event: MouseEvent) => void\n}\n\n// =============================================================================\n// Built-in Icons\n// =============================================================================\n\nconst BUILTIN_ICONS: Record<TimelineIconType, string> = {\n circle: `<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 16 16\" fill=\"currentColor\" aria-hidden=\"true\"><circle cx=\"8\" cy=\"8\" r=\"6\" /></svg>`,\n dot: `<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 16 16\" fill=\"currentColor\" aria-hidden=\"true\"><circle cx=\"8\" cy=\"8\" r=\"4\" /></svg>`,\n check: `<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 16 16\" fill=\"currentColor\" aria-hidden=\"true\"><path fill-rule=\"evenodd\" d=\"M12.416 3.376a.75.75 0 0 1 .208 1.04l-5 7.5a.75.75 0 0 1-1.154.114l-3-3a.75.75 0 0 1 1.06-1.06l2.353 2.353 4.493-6.739a.75.75 0 0 1 1.04-.208Z\" clip-rule=\"evenodd\" /></svg>`,\n warning: `<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 16 16\" fill=\"currentColor\" aria-hidden=\"true\"><path fill-rule=\"evenodd\" d=\"M6.701 2.25c.577-1 2.02-1 2.598 0l5.196 9a1.5 1.5 0 0 1-1.299 2.25H2.804a1.5 1.5 0 0 1-1.3-2.25l5.197-9ZM8 4a.75.75 0 0 1 .75.75v3a.75.75 0 0 1-1.5 0v-3A.75.75 0 0 1 8 4Zm0 8a1 1 0 1 0 0-2 1 1 0 0 0 0 2Z\" clip-rule=\"evenodd\" /></svg>`,\n error: `<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 16 16\" fill=\"currentColor\" aria-hidden=\"true\"><path fill-rule=\"evenodd\" d=\"M8 15A7 7 0 1 0 8 1a7 7 0 0 0 0 14ZM8 4a.75.75 0 0 1 .75.75v3a.75.75 0 0 1-1.5 0v-3A.75.75 0 0 1 8 4Zm0 8a1 1 0 1 0 0-2 1 1 0 0 0 0 2Z\" clip-rule=\"evenodd\" /></svg>`,\n info: `<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 16 16\" fill=\"currentColor\" aria-hidden=\"true\"><path fill-rule=\"evenodd\" d=\"M15 8A7 7 0 1 1 1 8a7 7 0 0 1 14 0ZM9 5a1 1 0 1 1-2 0 1 1 0 0 1 2 0ZM6.75 8a.75.75 0 0 0 0 1.5h.75v1.75a.75.75 0 0 0 1.5 0v-2.5A.75.75 0 0 0 8.25 8h-1.5Z\" clip-rule=\"evenodd\" /></svg>`,\n clock: `<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 16 16\" fill=\"currentColor\" aria-hidden=\"true\"><path fill-rule=\"evenodd\" d=\"M1 8a7 7 0 1 1 14 0A7 7 0 0 1 1 8Zm7.75-4.25a.75.75 0 0 0-1.5 0V8c0 .414.336.75.75.75h3.25a.75.75 0 0 0 0-1.5h-2.5v-3.5Z\" clip-rule=\"evenodd\" /></svg>`,\n star: `<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 16 16\" fill=\"currentColor\" aria-hidden=\"true\"><path fill-rule=\"evenodd\" d=\"M8 1.75a.75.75 0 0 1 .692.462l1.41 3.393 3.664.293a.75.75 0 0 1 .428 1.317l-2.791 2.39.853 3.58a.75.75 0 0 1-1.12.814L8 11.95l-3.136 2.05a.75.75 0 0 1-1.12-.815l.853-3.58-2.79-2.39a.75.75 0 0 1 .427-1.316l3.663-.293 1.41-3.393A.75.75 0 0 1 8 1.75Z\" clip-rule=\"evenodd\" /></svg>`,\n user: `<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 16 16\" fill=\"currentColor\" aria-hidden=\"true\"><path d=\"M8 8a3 3 0 1 0 0-6 3 3 0 0 0 0 6ZM12.735 14c.618 0 1.093-.561.872-1.139a6.002 6.002 0 0 0-11.215 0c-.22.578.254 1.139.872 1.139h9.47Z\" /></svg>`,\n message: `<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 16 16\" fill=\"currentColor\" aria-hidden=\"true\"><path fill-rule=\"evenodd\" d=\"M1 8.74c0 .983.713 1.825 1.69 1.943.764.092 1.534.164 2.31.216v2.351a.75.75 0 0 0 1.28.53l2.51-2.51c.182-.181.427-.283.684-.287A23.109 23.109 0 0 0 14 10.67c.7-.123 1-.87 1-1.63v-4.6c0-.76-.3-1.51-1-1.63A23.056 23.056 0 0 0 8 2.25c-2.154 0-4.254.147-6 .56-.7.12-1 .87-1 1.63v4.3Z\" clip-rule=\"evenodd\" /></svg>`,\n}\n\n// =============================================================================\n// Helper Functions\n// =============================================================================\n\n/**\n * Dateオブジェクトに変換\n */\nfunction toDate(datetime: string | Date): Date {\n if (datetime instanceof Date) {\n return datetime\n }\n return new Date(datetime)\n}\n\n/**\n * 日付をフォーマット(YYYY/MM/DD形式)\n */\nfunction formatDate(date: Date): string {\n const year = date.getFullYear()\n const month = String(date.getMonth() + 1).padStart(2, '0')\n const day = String(date.getDate()).padStart(2, '0')\n return `${year}/${month}/${day}`\n}\n\n/**\n * 時間をフォーマット\n */\nfunction formatTime(date: Date, format: TimelineTimeFormat): string {\n if (format === 'none') {\n return ''\n }\n\n const hours = String(date.getHours()).padStart(2, '0')\n const minutes = String(date.getMinutes()).padStart(2, '0')\n\n if (format === 'HH:mm') {\n return `${hours}:${minutes}`\n }\n\n const seconds = String(date.getSeconds()).padStart(2, '0')\n return `${hours}:${minutes}:${seconds}`\n}\n\n/**\n * HTMLをサニタイズ(XSS対策)\n * 安全なHTML要素と属性のみを許可\n */\nfunction sanitizeHtml(input: string): string {\n const parser = new DOMParser()\n const doc = parser.parseFromString(input, 'text/html')\n\n // 危険な要素を完全に削除\n const dangerousElements = [\n 'script', 'iframe', 'object', 'embed', 'form', 'input', 'button',\n 'textarea', 'select', 'style', 'link', 'meta', 'base', 'noscript',\n ]\n dangerousElements.forEach((tag) => {\n doc.querySelectorAll(tag).forEach((el) => el.remove())\n })\n\n // 危険な属性を全要素から削除(イベントハンドラ等)\n const dangerousAttrs = [\n 'onload', 'onerror', 'onclick', 'onmouseover', 'onmouseout', 'onmousedown',\n 'onmouseup', 'onfocus', 'onblur', 'onkeydown', 'onkeyup', 'onkeypress',\n 'onsubmit', 'onreset', 'onchange', 'oninput', 'onscroll', 'onresize',\n 'onanimationstart', 'onanimationend', 'ontransitionend', 'oncontextmenu',\n 'ondblclick', 'ondrag', 'ondragend', 'ondragenter', 'ondragleave',\n 'ondragover', 'ondragstart', 'ondrop', 'onmouseenter', 'onmouseleave',\n 'onmousemove', 'onwheel', 'oncopy', 'oncut', 'onpaste', 'onabort',\n 'oncanplay', 'oncanplaythrough', 'oncuechange', 'ondurationchange',\n 'onemptied', 'onended', 'onloadeddata', 'onloadedmetadata', 'onloadstart',\n 'onpause', 'onplay', 'onplaying', 'onprogress', 'onratechange', 'onseeked',\n 'onseeking', 'onstalled', 'onsuspend', 'ontimeupdate', 'onvolumechange',\n 'onwaiting', 'ontoggle', 'onpointerdown', 'onpointerup', 'onpointermove',\n 'onpointerenter', 'onpointerleave', 'onpointercancel', 'ongotpointercapture',\n 'onlostpointercapture', 'ontouchstart', 'ontouchmove', 'ontouchend',\n 'ontouchcancel',\n ]\n\n doc.querySelectorAll('*').forEach((el) => {\n // イベントハンドラ属性を削除\n dangerousAttrs.forEach((attr) => el.removeAttribute(attr))\n\n // javascript: URLを削除\n const href = el.getAttribute('href')\n if (href && href.toLowerCase().trim().startsWith('javascript:')) {\n el.removeAttribute('href')\n }\n\n const src = el.getAttribute('src')\n if (src && src.toLowerCase().trim().startsWith('javascript:')) {\n el.removeAttribute('src')\n }\n\n // data: URLは画像以外では危険なので削除\n if (src && src.toLowerCase().trim().startsWith('data:') && el.tagName.toLowerCase() !== 'img') {\n el.removeAttribute('src')\n }\n\n // style属性からjavascript:やexpression()を削除\n const style = el.getAttribute('style')\n if (style) {\n const sanitizedStyle = style\n .replace(/javascript:/gi, '')\n .replace(/expression\\s*\\(/gi, '')\n .replace(/url\\s*\\(\\s*[\"']?\\s*javascript:/gi, 'url(')\n el.setAttribute('style', sanitizedStyle)\n }\n })\n\n return doc.body.innerHTML\n}\n\n/**\n * カスタムSVGアイコンをサニタイズ\n */\nfunction sanitizeSvgIcon(input: string): string | null {\n const trimmed = input.trim()\n\n if (!trimmed.toLowerCase().startsWith('<svg') || !trimmed.toLowerCase().endsWith('</svg>')) {\n return null\n }\n\n const parser = new DOMParser()\n const doc = parser.parseFromString(trimmed, 'image/svg+xml')\n\n const parserError = doc.querySelector('parsererror')\n if (parserError) {\n return null\n }\n\n const svg = doc.querySelector('svg')\n if (!svg) {\n return null\n }\n\n const dangerousElements = ['script', 'foreignObject', 'iframe', 'object', 'embed', 'use']\n dangerousElements.forEach((tag) => {\n svg.querySelectorAll(tag).forEach((el) => el.remove())\n })\n\n const dangerousAttrs = [\n 'onload', 'onerror', 'onclick', 'onmouseover', 'onmouseout', 'onmousedown',\n 'onmouseup', 'onfocus', 'onblur', 'onkeydown', 'onkeyup', 'onkeypress',\n 'onsubmit', 'onreset', 'onchange', 'oninput', 'onscroll', 'onresize',\n 'onanimationstart', 'onanimationend', 'ontransitionend',\n ]\n\n dangerousAttrs.forEach((attr) => svg.removeAttribute(attr))\n const svgHref = svg.getAttribute('href') ?? svg.getAttribute('xlink:href')\n if (svgHref && svgHref.toLowerCase().startsWith('javascript:')) {\n svg.removeAttribute('href')\n svg.removeAttribute('xlink:href')\n }\n\n svg.querySelectorAll('*').forEach((el) => {\n dangerousAttrs.forEach((attr) => el.removeAttribute(attr))\n const href = el.getAttribute('href') ?? el.getAttribute('xlink:href')\n if (href && href.toLowerCase().startsWith('javascript:')) {\n el.removeAttribute('href')\n el.removeAttribute('xlink:href')\n }\n })\n\n return svg.outerHTML\n}\n\n// =============================================================================\n// Timeline Class\n// =============================================================================\n\n/**\n * タイムラインコンポーネント\n */\nexport class Timeline {\n private config: TimelineConfig\n private container: HTMLElement\n private callbacks: TimelineCallbacks\n private state: TimelineState\n private itemClickElements: Array<{ element: HTMLElement; handler: (event: MouseEvent) => void }> = []\n\n constructor(\n container: HTMLElement,\n config: TimelineConfig,\n callbacks: TimelineCallbacks = {}\n ) {\n this.container = container\n this.config = config\n this.callbacks = callbacks\n this.state = this.createInitialState()\n }\n\n // ===========================================================================\n // Public Methods\n // ===========================================================================\n\n /**\n * タイムラインをレンダリング\n */\n render(): void {\n this.cleanup()\n clearElement(this.container)\n\n this.container.className = 'mokkun-timeline'\n this.container.setAttribute('role', 'list')\n this.container.setAttribute('aria-label', 'タイムライン')\n\n const list = createElement('ol', {\n className: 'timeline-list',\n })\n\n this.config.items.forEach((item, index) => {\n const itemEl = this.renderItem(item, index)\n list.appendChild(itemEl)\n })\n\n this.container.appendChild(list)\n }\n\n /**\n * アイテムを追加\n */\n addItem(item: TimelineItemConfig): void {\n this.config = {\n ...this.config,\n items: [...this.config.items, item],\n }\n this.state = this.createInitialState()\n this.render()\n }\n\n /**\n * アイテムを削除\n */\n removeItem(index: number): void {\n if (index < 0 || index >= this.config.items.length) {\n return\n }\n\n this.config = {\n ...this.config,\n items: this.config.items.filter((_, i) => i !== index),\n }\n this.state = this.createInitialState()\n this.render()\n }\n\n /**\n * アイテムを更新\n */\n updateItem(index: number, item: Partial<TimelineItemConfig>): void {\n if (index < 0 || index >= this.config.items.length) {\n return\n }\n\n this.config = {\n ...this.config,\n items: this.config.items.map((existingItem, i) =>\n i === index ? { ...existingItem, ...item } : existingItem\n ),\n }\n this.state = this.createInitialState()\n this.render()\n }\n\n /**\n * 現在の状態を取得\n */\n getState(): Readonly<TimelineState> {\n return { ...this.state }\n }\n\n /**\n * アイテム数を取得\n */\n getItemCount(): number {\n return this.config.items.length\n }\n\n /**\n * コンポーネントを破棄\n */\n destroy(): void {\n this.cleanup()\n clearElement(this.container)\n }\n\n // ===========================================================================\n // Private Methods\n // ===========================================================================\n\n /**\n * 初期状態を作成\n */\n private createInitialState(): TimelineState {\n const currentIndex = this.config.items.findIndex((item) => item.current)\n return {\n itemCount: this.config.items.length,\n currentIndex,\n }\n }\n\n /**\n * イベントハンドラーをクリーンアップ\n */\n private cleanup(): void {\n this.itemClickElements.forEach(({ element, handler }) => {\n element.removeEventListener('click', handler)\n })\n this.itemClickElements = []\n }\n\n /**\n * アイテムをレンダリング\n */\n private renderItem(item: TimelineItemConfig, index: number): HTMLElement {\n const isFirst = index === 0\n const isLast = index === this.config.items.length - 1\n const isCurrent = item.current ?? false\n\n const li = createElement('li', {\n className: [\n 'timeline-item',\n isCurrent ? 'is-current' : '',\n isFirst ? 'is-first' : '',\n isLast ? 'is-last' : '',\n ].filter(Boolean).join(' '),\n })\n li.setAttribute('role', 'listitem')\n\n // マーカーエリア(アイコン + 接続線)\n const markerArea = this.renderMarkerArea(item, isLast)\n li.appendChild(markerArea)\n\n // コンテンツエリア\n const contentArea = this.renderContentArea(item, index)\n li.appendChild(contentArea)\n\n return li\n }\n\n /**\n * マーカーエリアをレンダリング\n */\n private renderMarkerArea(item: TimelineItemConfig, isLast: boolean): HTMLElement {\n const markerArea = createElement('div', {\n className: 'timeline-marker-area',\n })\n\n // アイコン\n const iconWrapper = createElement('span', {\n className: [\n 'timeline-icon',\n item.current ? 'is-current' : '',\n ].filter(Boolean).join(' '),\n })\n iconWrapper.setAttribute('aria-hidden', 'true')\n\n if (item.iconColor) {\n iconWrapper.style.color = item.iconColor\n }\n\n const iconHtml = this.getIconHtml(item.icon)\n if (iconHtml) {\n iconWrapper.innerHTML = iconHtml\n }\n\n markerArea.appendChild(iconWrapper)\n\n // 接続線(最後のアイテム以外)\n if (!isLast) {\n const line = createElement('span', {\n className: 'timeline-line',\n })\n markerArea.appendChild(line)\n }\n\n return markerArea\n }\n\n /**\n * コンテンツエリアをレンダリング\n */\n private renderContentArea(item: TimelineItemConfig, index: number): HTMLElement {\n const contentArea = createElement('div', {\n className: 'timeline-content-area',\n })\n\n // ヘッダー(日時 + サイドアクション)\n const header = this.renderHeader(item)\n contentArea.appendChild(header)\n\n // タイトル\n if (item.title) {\n const title = createElement('div', {\n className: [\n 'timeline-title',\n item.current ? 'is-current' : '',\n ].filter(Boolean).join(' '),\n textContent: item.title,\n })\n contentArea.appendChild(title)\n }\n\n // コンテンツ\n const content = createElement('div', {\n className: 'timeline-content',\n })\n content.innerHTML = sanitizeHtml(item.content)\n contentArea.appendChild(content)\n\n // クリックハンドラー\n if (this.callbacks.onItemClick) {\n contentArea.classList.add('is-clickable')\n const handler = (event: MouseEvent) => {\n this.callbacks.onItemClick?.(index, event)\n }\n this.itemClickElements.push({ element: contentArea, handler })\n contentArea.addEventListener('click', handler)\n }\n\n return contentArea\n }\n\n /**\n * ヘッダーをレンダリング\n */\n private renderHeader(item: TimelineItemConfig): HTMLElement {\n const header = createElement('div', {\n className: 'timeline-header',\n })\n\n // 日時エリア\n const dateArea = createElement('div', {\n className: 'timeline-date-area',\n })\n\n // 日付\n const date = toDate(item.datetime)\n const dateLabel = item.dateLabel ?? formatDate(date)\n const dateEl = createElement('time', {\n className: [\n 'timeline-date',\n item.current ? 'is-current' : '',\n ].filter(Boolean).join(' '),\n textContent: dateLabel,\n })\n dateEl.setAttribute('datetime', date.toISOString())\n dateArea.appendChild(dateEl)\n\n // 時間\n const timeFormat = item.timeFormat ?? 'HH:mm'\n if (timeFormat !== 'none') {\n const timeStr = formatTime(date, timeFormat)\n if (timeStr) {\n const timeEl = createElement('span', {\n className: 'timeline-time',\n textContent: timeStr,\n })\n dateArea.appendChild(timeEl)\n }\n }\n\n // 日付サフィックスエリア\n if (item.dateSuffixArea) {\n const suffixEl = createElement('span', {\n className: 'timeline-date-suffix',\n })\n suffixEl.innerHTML = sanitizeHtml(item.dateSuffixArea)\n dateArea.appendChild(suffixEl)\n }\n\n header.appendChild(dateArea)\n\n // サイドアクションエリア\n if (item.sideActionArea) {\n const sideActionEl = createElement('div', {\n className: 'timeline-side-action',\n })\n sideActionEl.innerHTML = sanitizeHtml(item.sideActionArea)\n header.appendChild(sideActionEl)\n }\n\n return header\n }\n\n /**\n * アイコンHTMLを取得\n */\n private getIconHtml(icon?: TimelineIconType | string): string {\n if (!icon) {\n return BUILTIN_ICONS.dot\n }\n\n const builtinIcon = BUILTIN_ICONS[icon as TimelineIconType]\n if (builtinIcon) {\n return builtinIcon\n }\n\n const sanitized = sanitizeSvgIcon(icon)\n return sanitized ?? BUILTIN_ICONS.dot\n }\n\n // ===========================================================================\n // Static Field Renderer\n // ===========================================================================\n\n static renderField(field: InputField): string {\n const timelineHtml = `\n <div class=\"mokkun-timeline\">\n <div class=\"timeline-item\">\n <div class=\"timeline-marker\"></div>\n <div class=\"timeline-content\">\n <div class=\"timeline-time\">10:30</div>\n <div class=\"timeline-title\">アクティビティ1</div>\n </div>\n </div>\n <div class=\"timeline-item\">\n <div class=\"timeline-marker\"></div>\n <div class=\"timeline-content\">\n <div class=\"timeline-time\">09:15</div>\n <div class=\"timeline-title\">アクティビティ2</div>\n </div>\n </div>\n <div class=\"timeline-item\">\n <div class=\"timeline-marker\"></div>\n <div class=\"timeline-content\">\n <div class=\"timeline-time\">08:00</div>\n <div class=\"timeline-title\">アクティビティ3</div>\n </div>\n </div>\n </div>\n `\n return createFieldWrapper(field, timelineHtml)\n }\n}\n\n// =============================================================================\n// Factory Function\n// =============================================================================\n\n/**\n * タイムラインを作成\n */\nexport function createTimeline(\n container: HTMLElement,\n config: TimelineConfig,\n callbacks: TimelineCallbacks = {}\n): Timeline {\n const timeline = new Timeline(container, config, callbacks)\n timeline.render()\n return timeline\n}\n","import { createElement } from '../utils/dom'\nimport { escapeHtml, createFieldWrapper } from '../utils/field-helpers'\nimport type { InputField } from '../../types/schema'\n\n/**\n * Chip component state\n */\nexport interface ChipState {\n /** Whether the chip is selected */\n selected: boolean\n /** Whether the chip is disabled */\n disabled: boolean\n}\n\n/**\n * Chip component callbacks\n */\nexport interface ChipCallbacks {\n /** Called when chip is clicked (selection toggle) */\n onClick?: (selected: boolean, state: ChipState) => void\n /** Called when delete button is clicked */\n onDelete?: (state: ChipState) => void\n}\n\n/**\n * Chip component configuration\n */\nexport interface ChipConfig {\n /** Label text for the chip */\n label: string\n /** Icon to display before the label (emoji, SVG path, or HTML string) */\n icon?: string\n /** Whether to show delete button */\n deletable?: boolean\n /** Whether the chip is selected by default */\n selected?: boolean\n /** Whether the chip is disabled */\n disabled?: boolean\n /** Size variant */\n size?: 'small' | 'medium' | 'large'\n /** Color variant */\n color?: 'default' | 'primary' | 'success' | 'warning' | 'error' | 'info'\n /** Accessible label for screen readers */\n ariaLabel?: string\n}\n\n/**\n * Chip component\n *\n * A small UI element for displaying tags, filter conditions, or categories.\n * Supports selection toggle, delete button, icons, and color variations.\n *\n * @example\n * ```typescript\n * const chip = createChip(container, {\n * label: 'JavaScript',\n * icon: '🚀',\n * deletable: true,\n * color: 'primary'\n * }, {\n * onClick: (selected) => console.log('Selected:', selected),\n * onDelete: () => console.log('Deleted')\n * })\n * ```\n */\nexport class Chip {\n private config: ChipConfig\n private state: ChipState\n private callbacks: ChipCallbacks\n private container: HTMLElement\n\n constructor(\n container: HTMLElement,\n config: ChipConfig,\n callbacks: ChipCallbacks = {}\n ) {\n this.container = container\n this.config = {\n size: 'medium',\n color: 'default',\n deletable: false,\n selected: false,\n disabled: false,\n ...config,\n }\n this.callbacks = callbacks\n this.state = this.createInitialState()\n }\n\n /**\n * Create initial component state\n */\n private createInitialState(): ChipState {\n return {\n selected: this.config.selected ?? false,\n disabled: this.config.disabled ?? false,\n }\n }\n\n /**\n * Render the chip component\n */\n render(): void {\n this.container.innerHTML = ''\n const chipElement = this.renderChip()\n this.container.appendChild(chipElement)\n }\n\n /**\n * Render the chip element\n */\n private renderChip(): HTMLElement {\n const chipWrapper = createElement('div', {\n className: `mokkun-chip chip-${this.config.size} chip-${this.config.color}`,\n attributes: {\n role: 'button',\n 'aria-label': this.config.ariaLabel || this.config.label,\n 'aria-pressed': String(this.state.selected),\n 'aria-disabled': String(this.state.disabled),\n tabindex: this.state.disabled ? '-1' : '0',\n 'data-selected': String(this.state.selected),\n 'data-disabled': String(this.state.disabled),\n 'data-color': this.config.color || 'default',\n },\n })\n\n // Add event listeners for selection toggle\n if (!this.state.disabled) {\n chipWrapper.addEventListener('click', (e) => {\n // Don't toggle if clicking delete button\n const target = e.target as HTMLElement\n if (target.closest('.chip-delete-button')) {\n return\n }\n this.handleChipClick()\n })\n\n chipWrapper.addEventListener('keydown', (e) => {\n if (e.key === 'Enter' || e.key === ' ') {\n e.preventDefault()\n // Don't toggle if focus is on delete button\n const target = e.target as HTMLElement\n if (target.closest('.chip-delete-button')) {\n return\n }\n this.handleChipClick()\n }\n })\n }\n\n // Create chip content container\n const chipContent = createElement('div', {\n className: 'chip-content',\n })\n\n // Add icon if provided\n if (this.config.icon) {\n const iconElement = createElement('span', {\n className: 'chip-icon',\n attributes: {\n 'aria-hidden': 'true',\n },\n })\n\n // Check if icon is an emoji or HTML\n if (this.config.icon.startsWith('<')) {\n iconElement.innerHTML = this.config.icon\n } else {\n iconElement.textContent = this.config.icon\n }\n\n chipContent.appendChild(iconElement)\n }\n\n // Add label\n const labelElement = createElement('span', {\n className: 'chip-label',\n textContent: this.config.label,\n })\n chipContent.appendChild(labelElement)\n\n chipWrapper.appendChild(chipContent)\n\n // Add delete button if deletable\n if (this.config.deletable) {\n const deleteButton = this.renderDeleteButton()\n chipWrapper.appendChild(deleteButton)\n }\n\n return chipWrapper\n }\n\n /**\n * Render the delete button\n */\n private renderDeleteButton(): HTMLElement {\n const deleteButton = createElement('button', {\n className: 'chip-delete-button',\n attributes: {\n type: 'button',\n 'aria-label': `Delete ${this.config.label}`,\n tabindex: this.state.disabled ? '-1' : '0',\n },\n })\n\n // Delete icon (×)\n const deleteIcon = createElement('span', {\n className: 'chip-delete-icon',\n attributes: {\n 'aria-hidden': 'true',\n },\n textContent: '×',\n })\n deleteButton.appendChild(deleteIcon)\n\n // Add click handler\n if (!this.state.disabled) {\n deleteButton.addEventListener('click', (e) => {\n e.stopPropagation() // Prevent chip click\n this.handleDelete()\n })\n\n deleteButton.addEventListener('keydown', (e) => {\n if (e.key === 'Enter' || e.key === ' ') {\n e.preventDefault()\n e.stopPropagation()\n this.handleDelete()\n }\n })\n }\n\n return deleteButton\n }\n\n /**\n * Handle chip click (selection toggle)\n */\n private handleChipClick(): void {\n if (this.state.disabled) {\n return\n }\n\n const newSelected = !this.state.selected\n this.setState({ selected: newSelected })\n\n if (this.callbacks.onClick) {\n this.callbacks.onClick(newSelected, { ...this.state })\n }\n }\n\n /**\n * Handle delete button click\n */\n private handleDelete(): void {\n if (this.state.disabled) {\n return\n }\n\n if (this.callbacks.onDelete) {\n this.callbacks.onDelete({ ...this.state })\n }\n }\n\n /**\n * Set the selected state\n */\n setSelected(selected: boolean): void {\n this.setState({ selected })\n }\n\n /**\n * Set the disabled state\n */\n setDisabled(disabled: boolean): void {\n this.setState({ disabled })\n }\n\n /**\n * Update component state\n */\n private setState(updates: Partial<ChipState>): void {\n const newState = { ...this.state, ...updates }\n\n // Only update if state actually changed\n if (JSON.stringify(newState) === JSON.stringify(this.state)) {\n return\n }\n\n this.state = newState\n this.render()\n }\n\n /**\n * Get current component state\n */\n getState(): ChipState {\n return { ...this.state }\n }\n\n /**\n * Update chip configuration\n */\n updateConfig(config: Partial<ChipConfig>): void {\n this.config = { ...this.config, ...config }\n this.render()\n }\n\n // ===========================================================================\n // Static Field Renderer\n // ===========================================================================\n\n static renderField(field: InputField): string {\n const chipField = field as InputField & {\n variant?: 'default' | 'primary' | 'success' | 'warning' | 'danger'\n removable?: boolean\n }\n const variant = chipField.variant ?? 'default'\n const removable = chipField.removable ?? false\n\n const chipHtml = `\n <span class=\"mokkun-chip chip-${variant}\">\n <span class=\"chip-label\">${escapeHtml(field.label)}</span>\n ${removable ? '<button type=\"button\" class=\"chip-remove\" aria-label=\"削除\">×</button>' : ''}\n </span>\n `\n return createFieldWrapper(field, chipHtml)\n }\n}\n\n/**\n * Factory function to create a Chip component\n *\n * @param container - HTMLElement to render the chip into\n * @param config - Chip configuration\n * @param callbacks - Event callbacks\n * @returns Chip instance\n */\nexport function createChip(\n container: HTMLElement,\n config: ChipConfig,\n callbacks: ChipCallbacks = {}\n): Chip {\n const chip = new Chip(container, config, callbacks)\n chip.render()\n return chip\n}\n","/**\n * StatusLabel Component\n * ステータスラベルコンポーネント\n *\n * \n * - タイプ(grey/blue/green/yellow/red/warning/error)\n * - 強調表示(bold)\n * - サイズ(small/medium)\n * - アイコン付き\n * - `data-type` / `data-size` / `data-bold` for styling\n * - `role=\"status\"` with `aria-label` for accessibility\n *\n * @see https://smarthr.design/products/components/status-label/\n */\n\nimport { createElement } from '../utils/dom'\nimport { escapeHtml, createFieldWrapper } from '../utils/field-helpers'\nimport type { InputField } from '../../types/schema'\n\n// =============================================================================\n// Types\n// =============================================================================\n\n/**\n * ステータスラベルのタイプ\n * - grey: 中立的な状態\n * - blue: 情報・進行中\n * - green: 成功・完了\n * - yellow: 注意\n * - red: エラー・緊急\n * - warning: 警告(黄色背景)\n * - error: エラー(赤背景)\n */\nexport type StatusLabelType = 'grey' | 'blue' | 'green' | 'yellow' | 'red' | 'warning' | 'error'\n\n/**\n * ステータスラベルのサイズ\n */\nexport type StatusLabelSize = 'small' | 'medium'\n\n/**\n * ビルトインアイコンタイプ\n */\nexport type StatusLabelIconType =\n | 'check'\n | 'warning'\n | 'error'\n | 'info'\n | 'clock'\n | 'circle'\n | 'dot'\n\n/**\n * ステータスラベルの状態\n */\nexport interface StatusLabelState {\n /** 表示テキスト */\n text: string\n /** 強調表示(背景と文字色を反転) */\n bold: boolean\n /** 非表示状態 */\n hidden: boolean\n}\n\n/**\n * ステータスラベルのコールバック\n */\nexport interface StatusLabelCallbacks {\n /** クリック時 */\n onClick?: (event: MouseEvent) => void\n}\n\n/**\n * ステータスラベルの設定\n */\nexport interface StatusLabelConfig {\n /** ラベルテキスト */\n text: string\n /** タイプ(カラー) */\n type?: StatusLabelType\n /** サイズ */\n size?: StatusLabelSize\n /** 強調表示 */\n bold?: boolean\n /** アイコン(ビルトインタイプまたはカスタムSVG) */\n icon?: StatusLabelIconType | string\n /** アイコンの位置 */\n iconPosition?: 'left' | 'right'\n /** ラベル(アクセシビリティ用) */\n label?: string\n /** クリック可能か */\n clickable?: boolean\n}\n\n// =============================================================================\n// Built-in Icons\n// =============================================================================\n\nconst BUILTIN_ICONS: Record<StatusLabelIconType, string> = {\n check: `<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 16 16\" fill=\"currentColor\" aria-hidden=\"true\"><path fill-rule=\"evenodd\" d=\"M12.416 3.376a.75.75 0 0 1 .208 1.04l-5 7.5a.75.75 0 0 1-1.154.114l-3-3a.75.75 0 0 1 1.06-1.06l2.353 2.353 4.493-6.739a.75.75 0 0 1 1.04-.208Z\" clip-rule=\"evenodd\" /></svg>`,\n warning: `<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 16 16\" fill=\"currentColor\" aria-hidden=\"true\"><path fill-rule=\"evenodd\" d=\"M6.701 2.25c.577-1 2.02-1 2.598 0l5.196 9a1.5 1.5 0 0 1-1.299 2.25H2.804a1.5 1.5 0 0 1-1.3-2.25l5.197-9ZM8 4a.75.75 0 0 1 .75.75v3a.75.75 0 0 1-1.5 0v-3A.75.75 0 0 1 8 4Zm0 8a1 1 0 1 0 0-2 1 1 0 0 0 0 2Z\" clip-rule=\"evenodd\" /></svg>`,\n error: `<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 16 16\" fill=\"currentColor\" aria-hidden=\"true\"><path fill-rule=\"evenodd\" d=\"M8 15A7 7 0 1 0 8 1a7 7 0 0 0 0 14ZM8 4a.75.75 0 0 1 .75.75v3a.75.75 0 0 1-1.5 0v-3A.75.75 0 0 1 8 4Zm0 8a1 1 0 1 0 0-2 1 1 0 0 0 0 2Z\" clip-rule=\"evenodd\" /></svg>`,\n info: `<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 16 16\" fill=\"currentColor\" aria-hidden=\"true\"><path fill-rule=\"evenodd\" d=\"M15 8A7 7 0 1 1 1 8a7 7 0 0 1 14 0ZM9 5a1 1 0 1 1-2 0 1 1 0 0 1 2 0ZM6.75 8a.75.75 0 0 0 0 1.5h.75v1.75a.75.75 0 0 0 1.5 0v-2.5A.75.75 0 0 0 8.25 8h-1.5Z\" clip-rule=\"evenodd\" /></svg>`,\n clock: `<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 16 16\" fill=\"currentColor\" aria-hidden=\"true\"><path fill-rule=\"evenodd\" d=\"M1 8a7 7 0 1 1 14 0A7 7 0 0 1 1 8Zm7.75-4.25a.75.75 0 0 0-1.5 0V8c0 .414.336.75.75.75h3.25a.75.75 0 0 0 0-1.5h-2.5v-3.5Z\" clip-rule=\"evenodd\" /></svg>`,\n circle: `<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 16 16\" fill=\"currentColor\" aria-hidden=\"true\"><circle cx=\"8\" cy=\"8\" r=\"6\" /></svg>`,\n dot: `<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 16 16\" fill=\"currentColor\" aria-hidden=\"true\"><circle cx=\"8\" cy=\"8\" r=\"4\" /></svg>`,\n}\n\n// =============================================================================\n// StatusLabel Class\n// =============================================================================\n\n/**\n * ステータスラベルコンポーネント\n */\nexport class StatusLabel {\n private config: StatusLabelConfig\n private state: StatusLabelState\n private callbacks: StatusLabelCallbacks\n private container: HTMLElement\n private clickHandler: ((event: MouseEvent) => void) | null = null\n\n constructor(\n container: HTMLElement,\n config: StatusLabelConfig,\n callbacks: StatusLabelCallbacks = {}\n ) {\n this.config = config\n this.container = container\n this.callbacks = callbacks\n this.state = this.createInitialState()\n }\n\n // ===========================================================================\n // Public Methods\n // ===========================================================================\n\n /**\n * ステータスラベルをレンダリング\n */\n render(): void {\n this.container.innerHTML = ''\n\n const type = this.config.type ?? 'grey'\n const size = this.config.size ?? 'medium'\n const bold = this.state.bold\n const clickable = this.config.clickable ?? false\n\n this.container.className = `mokkun-status-label status-label-${type} status-label-${size}`\n\n if (bold) {\n this.container.classList.add('status-label-bold')\n }\n\n if (clickable) {\n this.container.classList.add('status-label-clickable')\n }\n\n // data属性を設定\n this.container.setAttribute('data-type', type)\n this.container.setAttribute('data-size', size)\n if (bold) {\n this.container.setAttribute('data-bold', '')\n } else {\n this.container.removeAttribute('data-bold')\n }\n\n if (this.state.hidden) {\n this.container.setAttribute('data-hidden', '')\n this.container.style.display = 'none'\n return\n } else {\n this.container.removeAttribute('data-hidden')\n this.container.style.display = ''\n }\n\n // ラベル要素を作成\n const label = this.renderLabel()\n this.container.appendChild(label)\n\n // 既存のイベントリスナーを削除\n if (this.clickHandler) {\n this.container.removeEventListener('click', this.clickHandler)\n this.clickHandler = null\n }\n\n if (clickable && this.callbacks.onClick) {\n this.clickHandler = this.handleClick.bind(this)\n this.container.addEventListener('click', this.clickHandler)\n }\n }\n\n /**\n * テキストを設定\n */\n setText(text: string): void {\n if (this.state.text === text) {\n return\n }\n\n this.state = {\n ...this.state,\n text,\n }\n\n this.render()\n }\n\n /**\n * 強調表示を設定\n */\n setBold(bold: boolean): void {\n if (this.state.bold === bold) {\n return\n }\n\n this.state = {\n ...this.state,\n bold,\n }\n\n this.render()\n }\n\n /**\n * 非表示状態を設定\n */\n setHidden(hidden: boolean): void {\n if (this.state.hidden === hidden) {\n return\n }\n\n this.state = {\n ...this.state,\n hidden,\n }\n\n this.render()\n }\n\n /**\n * 現在のテキストを取得\n */\n getText(): string {\n return this.state.text\n }\n\n /**\n * 強調表示状態を取得\n */\n isBold(): boolean {\n return this.state.bold\n }\n\n /**\n * 現在の状態を取得\n */\n getState(): Readonly<StatusLabelState> {\n return { ...this.state }\n }\n\n /**\n * コンポーネントを破棄\n */\n destroy(): void {\n if (this.clickHandler) {\n this.container.removeEventListener('click', this.clickHandler)\n this.clickHandler = null\n }\n this.container.innerHTML = ''\n }\n\n // ===========================================================================\n // Private Methods\n // ===========================================================================\n\n /**\n * 初期状態を作成\n */\n private createInitialState(): StatusLabelState {\n return {\n text: this.config.text,\n bold: this.config.bold ?? false,\n hidden: false,\n }\n }\n\n /**\n * ラベル要素をレンダリング\n */\n private renderLabel(): HTMLElement {\n const label = createElement('span', {\n className: 'status-label-content',\n })\n\n // ARIA属性\n label.setAttribute('role', 'status')\n\n // アクセシビリティ用のラベル\n const ariaLabel = this.getAriaLabel()\n if (ariaLabel) {\n label.setAttribute('aria-label', ariaLabel)\n }\n\n const iconPosition = this.config.iconPosition ?? 'left'\n\n // アイコン(左)\n if (this.config.icon && iconPosition === 'left') {\n const iconEl = this.renderIcon()\n if (iconEl) {\n label.appendChild(iconEl)\n }\n }\n\n // テキスト\n const textSpan = createElement('span', {\n className: 'status-label-text',\n textContent: this.state.text,\n })\n label.appendChild(textSpan)\n\n // アイコン(右)\n if (this.config.icon && iconPosition === 'right') {\n const iconEl = this.renderIcon()\n if (iconEl) {\n label.appendChild(iconEl)\n }\n }\n\n return label\n }\n\n /**\n * アイコン要素をレンダリング\n */\n private renderIcon(): HTMLElement | null {\n if (!this.config.icon) {\n return null\n }\n\n const iconWrapper = createElement('span', {\n className: 'status-label-icon',\n attributes: {\n 'aria-hidden': 'true',\n },\n })\n\n // ビルトインアイコンをチェック\n const builtinIcon = BUILTIN_ICONS[this.config.icon as StatusLabelIconType]\n if (builtinIcon) {\n iconWrapper.innerHTML = builtinIcon\n } else {\n // カスタムSVGとして扱う(サニタイズ処理)\n const sanitizedSvg = this.sanitizeSvgIcon(this.config.icon)\n if (sanitizedSvg) {\n iconWrapper.innerHTML = sanitizedSvg\n }\n }\n\n return iconWrapper\n }\n\n /**\n * カスタムSVGアイコンをサニタイズ\n * XSS攻撃を防ぐため、SVG要素のみを許可し、危険な属性を削除する\n */\n private sanitizeSvgIcon(input: string): string | null {\n const trimmed = input.trim()\n\n // SVG要素でなければ拒否\n if (!trimmed.toLowerCase().startsWith('<svg') || !trimmed.toLowerCase().endsWith('</svg>')) {\n return null\n }\n\n // DOMパーサーでSVGを解析\n const parser = new DOMParser()\n const doc = parser.parseFromString(trimmed, 'image/svg+xml')\n\n // パースエラーがある場合は拒否\n const parserError = doc.querySelector('parsererror')\n if (parserError) {\n return null\n }\n\n const svg = doc.querySelector('svg')\n if (!svg) {\n return null\n }\n\n // 危険な要素を削除(script, foreignObject, iframe等)\n const dangerousElements = ['script', 'foreignObject', 'iframe', 'object', 'embed', 'use']\n dangerousElements.forEach((tag) => {\n svg.querySelectorAll(tag).forEach((el) => el.remove())\n })\n\n // 危険な属性を全要素から削除(イベントハンドラ等)\n const dangerousAttrs = [\n 'onload', 'onerror', 'onclick', 'onmouseover', 'onmouseout', 'onmousedown',\n 'onmouseup', 'onfocus', 'onblur', 'onkeydown', 'onkeyup', 'onkeypress',\n 'onsubmit', 'onreset', 'onchange', 'oninput', 'onscroll', 'onresize',\n 'onanimationstart', 'onanimationend', 'ontransitionend',\n ]\n\n // SVG要素自体の属性もサニタイズ\n dangerousAttrs.forEach((attr) => svg.removeAttribute(attr))\n const svgHref = svg.getAttribute('href') ?? svg.getAttribute('xlink:href')\n if (svgHref && svgHref.toLowerCase().startsWith('javascript:')) {\n svg.removeAttribute('href')\n svg.removeAttribute('xlink:href')\n }\n\n // 子要素の属性もサニタイズ\n svg.querySelectorAll('*').forEach((el) => {\n dangerousAttrs.forEach((attr) => el.removeAttribute(attr))\n // href/xlink:hrefがjavascript:の場合も削除\n const href = el.getAttribute('href') ?? el.getAttribute('xlink:href')\n if (href && href.toLowerCase().startsWith('javascript:')) {\n el.removeAttribute('href')\n el.removeAttribute('xlink:href')\n }\n })\n\n return svg.outerHTML\n }\n\n /**\n * アクセシビリティ用のラベルを取得\n */\n private getAriaLabel(): string {\n if (this.config.label) {\n return this.config.label\n }\n return this.state.text\n }\n\n /**\n * クリックイベントハンドラー\n */\n private handleClick(event: MouseEvent): void {\n this.callbacks.onClick?.(event)\n }\n\n // ===========================================================================\n // Static Field Renderer\n // ===========================================================================\n\n static renderField(field: InputField): string {\n const statusField = field as InputField & {\n variant?: 'default' | 'primary' | 'success' | 'warning' | 'danger' | 'info'\n }\n const variant = statusField.variant ?? 'default'\n\n const statusHtml = `\n <span class=\"mokkun-status-label status-${variant}\">\n <span class=\"status-dot\"></span>\n <span class=\"status-text\">${escapeHtml(field.label)}</span>\n </span>\n `\n return createFieldWrapper(field, statusHtml)\n }\n}\n\n// =============================================================================\n// Factory Function\n// =============================================================================\n\n/**\n * ステータスラベルを作成\n */\nexport function createStatusLabel(\n container: HTMLElement,\n config: StatusLabelConfig,\n callbacks: StatusLabelCallbacks = {}\n): StatusLabel {\n const statusLabel = new StatusLabel(container, config, callbacks)\n statusLabel.render()\n return statusLabel\n}\n","/**\n * SegmentedControl Component\n * セグメントコントロールコンポーネント\n *\n * Button group component for selecting one option from multiple choices:\n * - Size variations (small/medium)\n * - Icon support for options\n * - Disabled state (group and per-option)\n * - Full-width display\n * - Full ARIA compliance with keyboard navigation\n *\n * Use cases:\n * - View switching (list/grid)\n * - Filter switching\n * - Tab alternative\n */\n\nimport { createElement } from '../utils/dom'\nimport { escapeHtml, createFieldWrapper } from '../utils/field-helpers'\nimport type { InputField } from '../../types/schema'\n\n// =============================================================================\n// Types\n// =============================================================================\n\n/**\n * セグメントコントロールのオプション\n */\nexport interface SegmentedControlOption {\n /** 値 */\n value: string\n /** ラベル */\n label: string\n /** アイコン(SVG文字列) */\n icon?: string\n /** 無効化 */\n disabled?: boolean\n}\n\n/**\n * セグメントコントロールの状態\n */\nexport interface SegmentedControlState {\n /** 選択された値 */\n selectedValue: string\n /** 無効化状態 */\n disabled: boolean\n /** フォーカスされているオプションのインデックス */\n focusedIndex: number\n}\n\n/**\n * セグメントコントロールのコールバック\n */\nexport interface SegmentedControlCallbacks {\n /** 値変更時(値と状態を受け取る) */\n onChange?: (value: string, state: SegmentedControlState) => void\n /** 値変更時(値のみを受け取る) - */\n onClickOption?: (value: string) => void\n}\n\n/**\n * セグメントコントロールの設定\n */\nexport interface SegmentedControlConfig {\n /** オプション配列(必須) */\n options: SegmentedControlOption[]\n /** 初期選択値 */\n value?: string\n /** サイズ: 's' (small) または 'default' (medium) - */\n size?: 's' | 'default'\n /** 無効化(グループ全体) */\n disabled?: boolean\n /** フル幅表示 */\n fullWidth?: boolean\n /** 幅(カスタム指定) */\n width?: string | number\n}\n\n// =============================================================================\n// SegmentedControl Class\n// =============================================================================\n\n/**\n * セグメントコントロールコンポーネント\n */\nexport class SegmentedControl {\n private config: SegmentedControlConfig\n private state: SegmentedControlState\n private callbacks: SegmentedControlCallbacks\n private container: HTMLElement\n private optionElements: HTMLElement[] = []\n\n constructor(\n container: HTMLElement,\n config: SegmentedControlConfig,\n callbacks: SegmentedControlCallbacks = {}\n ) {\n this.config = config\n this.container = container\n this.callbacks = callbacks\n this.state = this.createInitialState()\n }\n\n // ===========================================================================\n // Public Methods\n // ===========================================================================\n\n /**\n * セグメントコントロールをレンダリング\n */\n render(): void {\n this.container.innerHTML = ''\n this.optionElements = []\n\n const size = this.config.size ?? 'default'\n\n this.container.className = `mokkun-segmented-control segmented-${size === 's' ? 'small' : 'medium'}`\n\n if (this.config.fullWidth) {\n this.container.classList.add('segmented-full-width')\n }\n\n this.container.setAttribute('role', 'group')\n\n if (this.state.disabled) {\n this.container.setAttribute('data-disabled', '')\n } else {\n this.container.removeAttribute('data-disabled')\n }\n\n // 幅の設定\n if (this.config.width) {\n const width =\n typeof this.config.width === 'number'\n ? `${this.config.width}px`\n : this.config.width\n this.container.style.width = width\n } else if (this.config.fullWidth) {\n this.container.style.width = '100%'\n } else {\n this.container.style.width = ''\n }\n\n // オプションコンテナ\n const optionsContainer = createElement('div', {\n className: 'segmented-options',\n })\n\n // オプションをレンダリング\n this.config.options.forEach((option, index) => {\n const optionElement = this.renderOption(option, index)\n this.optionElements.push(optionElement)\n optionsContainer.appendChild(optionElement)\n })\n\n this.container.appendChild(optionsContainer)\n }\n\n /**\n * 値を設定\n */\n setValue(value: string): void {\n if (this.state.disabled) {\n return\n }\n\n const option = this.config.options.find((opt) => opt.value === value)\n if (!option || option.disabled) {\n return\n }\n\n if (this.state.selectedValue === value) {\n return\n }\n\n this.state = {\n ...this.state,\n selectedValue: value,\n }\n\n this.render()\n }\n\n /**\n * 無効化状態を設定\n */\n setDisabled(disabled: boolean): void {\n if (this.state.disabled === disabled) {\n return\n }\n\n this.state = {\n ...this.state,\n disabled,\n }\n\n this.render()\n }\n\n /**\n * 現在の状態を取得\n */\n getState(): SegmentedControlState {\n return { ...this.state }\n }\n\n /**\n * 現在の値を取得\n */\n getValue(): string {\n return this.state.selectedValue\n }\n\n /**\n * 無効化されているかどうかを取得\n */\n isDisabled(): boolean {\n return this.state.disabled\n }\n\n // ===========================================================================\n // Private Methods\n // ===========================================================================\n\n /**\n * 初期状態を作成\n */\n private createInitialState(): SegmentedControlState {\n // デフォルト値がない場合は最初の有効なオプションを選択\n const defaultValue =\n this.config.value ??\n this.config.options.find((opt) => !opt.disabled)?.value ??\n this.config.options[0]?.value ??\n ''\n\n return {\n selectedValue: defaultValue,\n disabled: this.config.disabled ?? false,\n focusedIndex: this.config.options.findIndex(\n (opt) => opt.value === defaultValue\n ),\n }\n }\n\n /**\n * オプションをレンダリング\n */\n private renderOption(\n option: SegmentedControlOption,\n index: number\n ): HTMLElement {\n const isSelected = this.state.selectedValue === option.value\n const isDisabled = this.state.disabled || option.disabled || false\n const isFocusable =\n isSelected ||\n (this.state.focusedIndex === -1 && index === 0) ||\n this.state.focusedIndex === index\n\n const button = createElement('button', {\n className: 'segmented-button',\n attributes: {\n type: 'button',\n 'aria-pressed': String(isSelected),\n 'aria-disabled': String(isDisabled),\n tabindex: isFocusable && !isDisabled ? '0' : '-1',\n 'data-value': option.value,\n },\n })\n\n if (isSelected) {\n button.classList.add('selected')\n }\n\n if (isDisabled) {\n button.classList.add('disabled')\n button.setAttribute('disabled', 'disabled')\n }\n\n // アイコン\n if (option.icon) {\n const iconWrapper = createElement('span', {\n className: 'segmented-icon',\n })\n iconWrapper.innerHTML = option.icon\n button.appendChild(iconWrapper)\n }\n\n // ラベル\n const labelSpan = createElement('span', {\n className: 'segmented-label',\n textContent: option.label,\n })\n button.appendChild(labelSpan)\n\n // イベントリスナー\n if (!isDisabled) {\n button.addEventListener('click', (e) => {\n e.preventDefault()\n this.handleOptionClick(option.value)\n })\n\n button.addEventListener('keydown', (e) => {\n this.handleKeyboardNavigation(e)\n })\n }\n\n return button\n }\n\n /**\n * オプションクリックを処理\n */\n private handleOptionClick(value: string): void {\n if (this.state.disabled) {\n return\n }\n\n const option = this.config.options.find((opt) => opt.value === value)\n if (!option || option.disabled) {\n return\n }\n\n if (this.state.selectedValue === value) {\n return\n }\n\n const optionIndex = this.config.options.findIndex(\n (opt) => opt.value === value\n )\n\n this.state = {\n ...this.state,\n selectedValue: value,\n focusedIndex: optionIndex,\n }\n\n this.render()\n\n // フォーカスを維持\n if (this.optionElements[optionIndex]) {\n this.optionElements[optionIndex].focus()\n }\n\n this.callbacks.onChange?.(value, this.state)\n this.callbacks.onClickOption?.(value)\n }\n\n /**\n * キーボードナビゲーションを処理\n */\n private handleKeyboardNavigation(e: KeyboardEvent): void {\n switch (e.key) {\n case 'ArrowRight':\n case 'ArrowDown':\n e.preventDefault()\n this.focusNextOption()\n break\n case 'ArrowLeft':\n case 'ArrowUp':\n e.preventDefault()\n this.focusPreviousOption()\n break\n case 'Home':\n e.preventDefault()\n this.focusFirstOption()\n break\n case 'End':\n e.preventDefault()\n this.focusLastOption()\n break\n case ' ':\n case 'Enter':\n e.preventDefault()\n const target = e.currentTarget as HTMLElement\n const value = target.getAttribute('data-value')\n if (value) {\n this.handleOptionClick(value)\n }\n break\n }\n }\n\n /**\n * 次のオプションにフォーカス\n */\n private focusNextOption(): void {\n let nextIndex = this.state.focusedIndex + 1\n while (nextIndex < this.config.options.length) {\n if (!this.config.options[nextIndex].disabled) {\n this.focusOption(nextIndex)\n return\n }\n nextIndex++\n }\n // ループ: 先頭に戻る\n this.focusFirstOption()\n }\n\n /**\n * 前のオプションにフォーカス\n */\n private focusPreviousOption(): void {\n let prevIndex = this.state.focusedIndex - 1\n while (prevIndex >= 0) {\n if (!this.config.options[prevIndex].disabled) {\n this.focusOption(prevIndex)\n return\n }\n prevIndex--\n }\n // ループ: 末尾に戻る\n this.focusLastOption()\n }\n\n /**\n * 最初の有効なオプションにフォーカス\n */\n private focusFirstOption(): void {\n for (let i = 0; i < this.config.options.length; i++) {\n if (!this.config.options[i].disabled) {\n this.focusOption(i)\n return\n }\n }\n }\n\n /**\n * 最後の有効なオプションにフォーカス\n */\n private focusLastOption(): void {\n for (let i = this.config.options.length - 1; i >= 0; i--) {\n if (!this.config.options[i].disabled) {\n this.focusOption(i)\n return\n }\n }\n }\n\n /**\n * 指定されたインデックスのオプションにフォーカス\n */\n private focusOption(index: number): void {\n if (index < 0 || index >= this.config.options.length) {\n return\n }\n\n const option = this.config.options[index]\n if (option.disabled) {\n return\n }\n\n this.state = {\n ...this.state,\n focusedIndex: index,\n }\n\n if (this.optionElements[index]) {\n // タブインデックスを更新\n this.optionElements.forEach((el, i) => {\n el.setAttribute('tabindex', i === index ? '0' : '-1')\n })\n this.optionElements[index].focus()\n }\n }\n\n // ===========================================================================\n // Static Field Renderer\n // ===========================================================================\n\n static renderField(field: InputField): string {\n const segmentedField = field as InputField & {\n options?: Array<{ value: string; label: string }>\n default?: string\n }\n const options = segmentedField.options ?? []\n const defaultValue = segmentedField.default ?? options[0]?.value\n\n const segmentedHtml = `\n <div class=\"mokkun-segmented-control\" role=\"radiogroup\" aria-label=\"${escapeHtml(field.label)}\">\n ${options.map(opt => `\n <button type=\"button\" class=\"segment-button ${opt.value === defaultValue ? 'active' : ''}\"\n role=\"radio\" aria-checked=\"${opt.value === defaultValue}\"\n data-value=\"${escapeHtml(opt.value)}\">\n ${escapeHtml(opt.label)}\n </button>\n `).join('')}\n </div>\n `\n return createFieldWrapper(field, segmentedHtml)\n }\n}\n\n// =============================================================================\n// Factory Function\n// =============================================================================\n\n/**\n * SegmentedControlを作成するファクトリ関数\n */\nexport function createSegmentedControl(\n container: HTMLElement,\n config: SegmentedControlConfig,\n callbacks: SegmentedControlCallbacks = {}\n): SegmentedControl {\n const control = new SegmentedControl(container, config, callbacks)\n control.render()\n return control\n}\n","/**\n * Tabs Component\n * タブUIコンポーネント\n */\n\nimport type { InputField } from '../../types'\nimport { createElement, clearElement, generateId } from '../utils/dom'\nimport { createFieldWrapper } from '../utils/field-helpers'\n\n// =============================================================================\n// Types\n// =============================================================================\n\n/**\n * 遅延読み込み関数の型\n */\nexport type LazyLoadFn = (tabId: string) => Promise<string>\n\n/**\n * タブ定義\n */\nexport interface TabDefinition {\n /** タブID(英数字、ハイフン、アンダースコアのみ推奨) */\n id: string\n /** タブラベル */\n label: string\n /**\n * タブアイコン(オプション)\n * @security HTML文字列として設定されるため、信頼されたソースからのみ使用すること\n */\n icon?: string\n /** アイコンの代替テキスト(アクセシビリティ用) */\n iconLabel?: string\n /** 無効化 */\n disabled?: boolean\n /** バッジ(通知数等) */\n badge?: string | number\n /** タブ内のフィールド */\n fields?: InputField[]\n /**\n * タブ内のカスタムコンテンツ(HTML文字列)\n * @security HTML文字列として設定されるため、信頼されたソースからのみ使用すること\n */\n content?: string\n /**\n * 遅延読み込み関数\n * @security 戻り値はHTML文字列として設定されるため、信頼されたソースからのみ使用すること\n */\n lazyLoad?: LazyLoadFn\n}\n\n/**\n * タブの状態\n */\nexport interface TabsState {\n /** 現在のアクティブタブID */\n activeTabId: string\n /** タブ一覧 */\n tabs: TabDefinition[]\n}\n\n/**\n * タブのコールバック\n */\nexport interface TabsCallbacks {\n /** タブ変更時 */\n onTabChange?: (tabId: string, state: TabsState) => void\n /** フィールドレンダラー */\n renderFields?: (fields: InputField[], container: HTMLElement) => void\n}\n\n/**\n * タブの設定\n */\nexport interface TabsConfig {\n /** タブ一覧 */\n tabs: TabDefinition[]\n /** 初期アクティブタブID */\n defaultActiveTab?: string\n /** タブの配置 */\n position?: 'top' | 'bottom' | 'left' | 'right'\n /** タブのスタイル */\n variant?: 'default' | 'pills' | 'underline' | 'bordered' | 'segmented'\n /** ボーダー表示 */\n bordered?: boolean\n /** スクロール有効化(タブが多い場合) */\n scrollable?: boolean\n /** URLハッシュとの同期 */\n syncWithHash?: boolean\n /** ハッシュのプレフィックス(例: \"section-\") */\n hashPrefix?: string\n}\n\n// =============================================================================\n// Tabs Class\n// =============================================================================\n\n/**\n * タブコンポーネント\n */\nexport class Tabs {\n private config: TabsConfig\n private state: TabsState\n private callbacks: TabsCallbacks\n private container: HTMLElement\n private instanceId: string\n private hashChangeHandler: ((e: HashChangeEvent) => void) | null = null\n private lazyLoadCache: Map<string, string> = new Map()\n private loadingTabs: Set<string> = new Set()\n\n constructor(\n config: TabsConfig,\n container: HTMLElement,\n callbacks: TabsCallbacks = {}\n ) {\n this.config = config\n this.container = container\n this.callbacks = callbacks\n this.instanceId = generateId('tabs')\n this.state = this.createInitialState()\n }\n\n // ===========================================================================\n // Public Methods\n // ===========================================================================\n\n /**\n * タブをレンダリング\n */\n render(): void {\n clearElement(this.container)\n\n const position = this.config.position ?? 'top'\n const variant = this.config.variant ?? 'default'\n const bordered = this.config.bordered ?? false\n const scrollable = this.config.scrollable ?? false\n\n const classNames = [\n 'mokkun-tabs',\n `tabs-${position}`,\n `tabs-${variant}`,\n bordered ? 'tabs-bordered' : '',\n scrollable ? 'tabs-scrollable' : '',\n ].filter(Boolean).join(' ')\n\n this.container.className = classNames\n\n const wrapper = createElement('div', { className: 'tabs-wrapper' })\n\n // 縦配置の場合はフレックス方向を調整\n if (position === 'left' || position === 'right') {\n wrapper.style.display = 'flex'\n wrapper.style.flexDirection = position === 'left' ? 'row' : 'row-reverse'\n }\n\n // タブヘッダー\n const tabList = this.renderTabList()\n wrapper.appendChild(tabList)\n\n // タブパネル\n const panels = this.renderPanels()\n wrapper.appendChild(panels)\n\n this.container.appendChild(wrapper)\n\n // URLハッシュ同期のセットアップ(重複登録を防止)\n if (this.config.syncWithHash && !this.hashChangeHandler) {\n this.setupHashSync()\n }\n\n // アクティブタブの遅延読み込みを実行\n this.loadLazyContent(this.state.activeTabId)\n }\n\n /**\n * タブを切り替え\n */\n setActiveTab(tabId: string): boolean {\n const tab = this.state.tabs.find(t => t.id === tabId)\n if (!tab || tab.disabled) {\n return false\n }\n\n if (this.state.activeTabId === tabId) {\n return true\n }\n\n this.state = {\n ...this.state,\n activeTabId: tabId,\n }\n\n this.render()\n this.callbacks.onTabChange?.(tabId, this.state)\n\n // URLハッシュを更新\n if (this.config.syncWithHash) {\n this.updateHash(tabId)\n }\n\n return true\n }\n\n /**\n * 次のタブへ移動\n */\n nextTab(): boolean {\n const currentIndex = this.state.tabs.findIndex(t => t.id === this.state.activeTabId)\n\n for (let i = currentIndex + 1; i < this.state.tabs.length; i++) {\n const tab = this.state.tabs[i]\n if (!tab.disabled) {\n return this.setActiveTab(tab.id)\n }\n }\n\n // 循環\n for (let i = 0; i < currentIndex; i++) {\n const tab = this.state.tabs[i]\n if (!tab.disabled) {\n return this.setActiveTab(tab.id)\n }\n }\n\n return false\n }\n\n /**\n * 前のタブへ移動\n */\n previousTab(): boolean {\n const currentIndex = this.state.tabs.findIndex(t => t.id === this.state.activeTabId)\n\n for (let i = currentIndex - 1; i >= 0; i--) {\n const tab = this.state.tabs[i]\n if (!tab.disabled) {\n return this.setActiveTab(tab.id)\n }\n }\n\n // 循環\n for (let i = this.state.tabs.length - 1; i > currentIndex; i--) {\n const tab = this.state.tabs[i]\n if (!tab.disabled) {\n return this.setActiveTab(tab.id)\n }\n }\n\n return false\n }\n\n /**\n * 現在の状態を取得\n */\n getState(): TabsState {\n return {\n ...this.state,\n tabs: this.state.tabs.map(t => ({ ...t })),\n }\n }\n\n /**\n * 現在のアクティブタブを取得\n */\n getActiveTab(): TabDefinition | undefined {\n return this.state.tabs.find(t => t.id === this.state.activeTabId)\n }\n\n /**\n * タブを追加\n */\n addTab(tab: TabDefinition, index?: number): void {\n const newTabs = [...this.state.tabs]\n if (index !== undefined && index >= 0 && index <= newTabs.length) {\n newTabs.splice(index, 0, tab)\n } else {\n newTabs.push(tab)\n }\n\n this.state = {\n ...this.state,\n tabs: newTabs,\n }\n\n this.render()\n }\n\n /**\n * タブを削除\n */\n removeTab(tabId: string): boolean {\n const index = this.state.tabs.findIndex(t => t.id === tabId)\n if (index === -1) {\n return false\n }\n\n const newTabs = this.state.tabs.filter(t => t.id !== tabId)\n\n // 削除されたタブがアクティブだった場合、別のタブをアクティブに\n let newActiveTabId = this.state.activeTabId\n if (this.state.activeTabId === tabId && newTabs.length > 0) {\n const enabledTab = newTabs.find(t => !t.disabled)\n newActiveTabId = enabledTab?.id ?? newTabs[0].id\n }\n\n this.state = {\n ...this.state,\n tabs: newTabs,\n activeTabId: newActiveTabId,\n }\n\n this.render()\n return true\n }\n\n /**\n * タブを更新\n */\n updateTab(tabId: string, updates: Partial<TabDefinition>): boolean {\n const index = this.state.tabs.findIndex(t => t.id === tabId)\n if (index === -1) {\n return false\n }\n\n this.state = {\n ...this.state,\n tabs: this.state.tabs.map(t =>\n t.id === tabId ? { ...t, ...updates } : t\n ),\n }\n\n this.render()\n return true\n }\n\n // ===========================================================================\n // Private Methods - Rendering\n // ===========================================================================\n\n /**\n * 初期状態を作成\n */\n private createInitialState(): TabsState {\n // URLハッシュから初期タブを取得\n let initialTabId: string | undefined\n if (this.config.syncWithHash) {\n initialTabId = this.getTabIdFromHash()\n }\n\n const defaultActiveTab = initialTabId\n ?? this.config.defaultActiveTab\n ?? this.config.tabs.find(t => !t.disabled)?.id\n ?? this.config.tabs[0]?.id\n ?? ''\n\n return {\n activeTabId: defaultActiveTab,\n tabs: [...this.config.tabs],\n }\n }\n\n /**\n * タブリストをレンダリング\n */\n private renderTabList(): HTMLElement {\n const tabList = createElement('div', {\n className: 'tabs-list',\n attributes: { role: 'tablist' },\n })\n\n for (const tab of this.state.tabs) {\n const tabButton = this.renderTabButton(tab)\n tabList.appendChild(tabButton)\n }\n\n // キーボードナビゲーション\n tabList.addEventListener('keydown', (e) => this.handleKeyDown(e))\n\n return tabList\n }\n\n /**\n * タブボタンをレンダリング\n */\n private renderTabButton(tab: TabDefinition): HTMLElement {\n const isActive = tab.id === this.state.activeTabId\n const className = [\n 'tab-button',\n isActive ? 'active' : '',\n tab.disabled ? 'disabled' : '',\n ].filter(Boolean).join(' ')\n\n const button = createElement('button', {\n className,\n attributes: {\n type: 'button',\n role: 'tab',\n 'aria-selected': String(isActive),\n 'aria-controls': `${this.instanceId}-panel-${tab.id}`,\n id: `${this.instanceId}-tab-${tab.id}`,\n tabindex: isActive ? '0' : '-1',\n },\n })\n\n if (tab.disabled) {\n button.setAttribute('aria-disabled', 'true')\n }\n\n // アイコン\n if (tab.icon) {\n const icon = createElement('span', {\n className: 'tab-icon',\n attributes: tab.iconLabel ? {\n 'aria-label': tab.iconLabel,\n role: 'img',\n } : {},\n })\n icon.innerHTML = tab.icon\n button.appendChild(icon)\n }\n\n // ラベル\n const label = createElement('span', {\n className: 'tab-label',\n textContent: tab.label,\n })\n button.appendChild(label)\n\n // バッジ\n if (tab.badge !== undefined) {\n const badge = createElement('span', {\n className: 'tab-badge',\n textContent: String(tab.badge),\n })\n button.appendChild(badge)\n }\n\n // クリックイベント\n if (!tab.disabled) {\n button.addEventListener('click', () => this.setActiveTab(tab.id))\n }\n\n return button\n }\n\n /**\n * パネルをレンダリング\n */\n private renderPanels(): HTMLElement {\n const panels = createElement('div', { className: 'tabs-panels' })\n\n for (const tab of this.state.tabs) {\n const panel = this.renderPanel(tab)\n panels.appendChild(panel)\n }\n\n return panels\n }\n\n /**\n * 個別パネルをレンダリング\n */\n private renderPanel(tab: TabDefinition): HTMLElement {\n const isActive = tab.id === this.state.activeTabId\n\n const panel = createElement('div', {\n className: `tab-panel ${isActive ? 'active' : ''}`,\n attributes: {\n role: 'tabpanel',\n id: `${this.instanceId}-panel-${tab.id}`,\n 'aria-labelledby': `${this.instanceId}-tab-${tab.id}`,\n hidden: isActive ? '' : 'true',\n },\n })\n\n if (isActive) {\n panel.removeAttribute('hidden')\n }\n\n // コンテンツをレンダリング\n if (tab.fields && this.callbacks.renderFields) {\n this.callbacks.renderFields(tab.fields, panel)\n } else if (tab.content) {\n panel.innerHTML = tab.content\n } else if (tab.fields) {\n // デフォルトのフィールドプレースホルダー\n for (const field of tab.fields) {\n const fieldEl = createElement('div', {\n className: 'field-placeholder',\n textContent: `[${field.type}] ${field.label}`,\n })\n panel.appendChild(fieldEl)\n }\n }\n\n return panel\n }\n\n /**\n * キーボードイベントを処理\n */\n private handleKeyDown(e: KeyboardEvent): void {\n const position = this.config.position ?? 'top'\n const isVertical = position === 'left' || position === 'right'\n\n switch (e.key) {\n case 'ArrowLeft':\n if (!isVertical) {\n e.preventDefault()\n this.previousTab()\n }\n break\n case 'ArrowRight':\n if (!isVertical) {\n e.preventDefault()\n this.nextTab()\n }\n break\n case 'ArrowUp':\n if (isVertical) {\n e.preventDefault()\n this.previousTab()\n }\n break\n case 'ArrowDown':\n if (isVertical) {\n e.preventDefault()\n this.nextTab()\n }\n break\n case 'Home':\n e.preventDefault()\n const firstEnabled = this.state.tabs.find(t => !t.disabled)\n if (firstEnabled) {\n this.setActiveTab(firstEnabled.id)\n }\n break\n case 'End':\n e.preventDefault()\n const lastEnabled = [...this.state.tabs].reverse().find(t => !t.disabled)\n if (lastEnabled) {\n this.setActiveTab(lastEnabled.id)\n }\n break\n }\n }\n\n // ===========================================================================\n // Private Methods - URL Hash Sync\n // ===========================================================================\n\n /**\n * URLハッシュ同期をセットアップ\n */\n private setupHashSync(): void {\n this.hashChangeHandler = () => {\n const tabId = this.getTabIdFromHash()\n if (tabId && tabId !== this.state.activeTabId) {\n const tab = this.state.tabs.find(t => t.id === tabId)\n if (tab && !tab.disabled) {\n this.state = {\n ...this.state,\n activeTabId: tabId,\n }\n this.render()\n this.callbacks.onTabChange?.(tabId, this.state)\n }\n }\n }\n window.addEventListener('hashchange', this.hashChangeHandler)\n }\n\n /**\n * ハッシュからタブIDを取得\n */\n private getTabIdFromHash(): string | undefined {\n const hash = window.location.hash.slice(1) // Remove '#'\n if (!hash) {\n return undefined\n }\n\n const prefix = this.config.hashPrefix ?? ''\n if (prefix && hash.startsWith(prefix)) {\n const tabId = hash.slice(prefix.length)\n const tab = this.state.tabs.find(t => t.id === tabId)\n return tab && !tab.disabled ? tabId : undefined\n }\n\n // Check if it's a valid tab ID\n const tab = this.config.tabs.find(t => t.id === hash)\n return tab && !tab.disabled ? hash : undefined\n }\n\n /**\n * URLハッシュを更新\n */\n private updateHash(tabId: string): void {\n const prefix = this.config.hashPrefix ?? ''\n window.location.hash = `${prefix}${tabId}`\n }\n\n // ===========================================================================\n // Private Methods - Lazy Loading\n // ===========================================================================\n\n /**\n * 遅延読み込みコンテンツを読み込む\n */\n private loadLazyContent(tabId: string): void {\n const tab = this.state.tabs.find(t => t.id === tabId)\n if (!tab?.lazyLoad) {\n return\n }\n\n // キャッシュがあれば使用\n if (this.lazyLoadCache.has(tabId)) {\n return\n }\n\n // 既に読み込み中\n if (this.loadingTabs.has(tabId)) {\n return\n }\n\n this.loadingTabs.add(tabId)\n\n // パネルにローディング表示\n const panel = this.container.querySelector(\n `#${this.instanceId}-panel-${tabId}`\n )\n if (panel) {\n const loadingDiv = createElement('div', {\n className: 'tab-loading',\n textContent: '読み込み中...',\n })\n clearElement(panel as HTMLElement)\n panel.appendChild(loadingDiv)\n }\n\n tab.lazyLoad(tabId)\n .then(content => {\n this.lazyLoadCache.set(tabId, content)\n this.loadingTabs.delete(tabId)\n\n // パネルにコンテンツを設定\n // Note: lazyLoadの戻り値はHTMLとして設定される(信頼されたソースからのコンテンツ前提)\n const currentPanel = this.container.querySelector(\n `#${this.instanceId}-panel-${tabId}`\n )\n if (currentPanel) {\n currentPanel.innerHTML = content\n }\n })\n .catch((error: Error) => {\n this.loadingTabs.delete(tabId)\n\n // パネルにエラー表示\n const currentPanel = this.container.querySelector(\n `#${this.instanceId}-panel-${tabId}`\n )\n if (currentPanel) {\n const errorDiv = createElement('div', {\n className: 'tab-error',\n textContent: `読み込みに失敗しました: ${error.message}`,\n })\n clearElement(currentPanel as HTMLElement)\n currentPanel.appendChild(errorDiv)\n }\n })\n }\n\n // ===========================================================================\n // Public Methods - Cleanup and Refresh\n // ===========================================================================\n\n /**\n * クリーンアップ(イベントリスナーの削除)\n */\n destroy(): void {\n if (this.hashChangeHandler) {\n window.removeEventListener('hashchange', this.hashChangeHandler)\n this.hashChangeHandler = null\n }\n this.lazyLoadCache.clear()\n this.loadingTabs.clear()\n clearElement(this.container)\n }\n\n /**\n * タブコンテンツを強制再読み込み\n */\n async refreshTabContent(tabId: string): Promise<void> {\n const tab = this.state.tabs.find(t => t.id === tabId)\n if (!tab?.lazyLoad) {\n return\n }\n\n // キャッシュをクリア\n this.lazyLoadCache.delete(tabId)\n\n // 再読み込み\n this.loadLazyContent(tabId)\n }\n\n // ===========================================================================\n // Static Field Renderer\n // ===========================================================================\n\n static renderField(field: InputField): string {\n const tabsHtml = `\n <div class=\"mokkun-tabs\">\n <div class=\"tabs-list\" role=\"tablist\">\n <button type=\"button\" class=\"tab-button active\" role=\"tab\" aria-selected=\"true\">タブ1</button>\n <button type=\"button\" class=\"tab-button\" role=\"tab\" aria-selected=\"false\">タブ2</button>\n <button type=\"button\" class=\"tab-button\" role=\"tab\" aria-selected=\"false\">タブ3</button>\n </div>\n <div class=\"tab-panel\" role=\"tabpanel\">\n <p>タブコンテンツがここに表示されます</p>\n </div>\n </div>\n `\n return createFieldWrapper(field, tabsHtml)\n }\n}\n","/**\n * LineClamp Component\n * 行数制限コンポーネント\n *\n * 機能:\n * - 行数指定(1-6行)\n * - 展開ボタン(「もっと見る」/「折りたたむ」)\n * - ツールチップでの全文表示\n * - 省略記号(...)表示\n */\n\nimport { createElement, generateId, escapeHtml } from '../utils/dom'\nimport { escapeHtml as escapeHtmlHelper, createFieldWrapper } from '../utils/field-helpers'\nimport type { InputField } from '../../types/schema'\nimport { Tooltip, type TooltipPosition } from './tooltip'\n\n// =============================================================================\n// Types\n// =============================================================================\n\n/**\n * 行数制限の値(1-6)\n */\nexport type MaxLines = 1 | 2 | 3 | 4 | 5 | 6\n\n/**\n * LineClampの状態\n */\nexport interface LineClampState {\n /** テキスト内容 */\n text: string\n /** 最大行数 */\n maxLines: MaxLines\n /** 展開中かどうか */\n expanded: boolean\n /** テキストが切り詰められているかどうか */\n clamped: boolean\n /** 展開ボタンを表示するか */\n showExpandButton: boolean\n /** ツールチップを表示するか */\n showTooltip: boolean\n /** ツールチップの位置 */\n tooltipPosition: TooltipPosition\n}\n\n/**\n * LineClampのコールバック\n */\nexport interface LineClampCallbacks {\n /** 展開時 */\n onExpand?: () => void\n /** 折りたたみ時 */\n onCollapse?: () => void\n /** トグル時(展開/折りたたみ) */\n onToggle?: (expanded: boolean) => void\n}\n\n/**\n * LineClampの設定\n */\nexport interface LineClampConfig {\n /** テキスト内容 */\n text: string\n /** 最大行数(1-6、デフォルト: 2) */\n maxLines: MaxLines\n /** HTMLコンテンツとして解釈するか(デフォルト: false) */\n isHtml?: boolean\n /** 展開ボタンを表示するか(デフォルト: false) */\n showExpandButton?: boolean\n /** 展開ボタンのラベル(デフォルト: 「もっと見る」) */\n expandButtonLabel?: string\n /** 折りたたみボタンのラベル(デフォルト: 「折りたたむ」) */\n collapseButtonLabel?: string\n /** ツールチップで全文を表示するか(デフォルト: true) */\n showTooltip?: boolean\n /** ツールチップの位置(デフォルト: top) */\n tooltipPosition?: TooltipPosition\n /** ツールチップの遅延時間(ミリ秒、デフォルト: 300) */\n tooltipDelay?: number\n}\n\n// =============================================================================\n// Helper Functions\n// =============================================================================\n\n/**\n * HTMLをサニタイズする(許可されたタグのみを保持)\n * XSS攻撃を防ぐために、scriptタグやイベントハンドラを除去\n */\nfunction sanitizeHtml(html: string): string {\n // 許可するタグ\n const allowedTags = ['strong', 'em', 'b', 'i', 'u', 'a', 'br', 'span', 'p']\n // 許可する属性\n const allowedAttributes: Record<string, string[]> = {\n a: ['href', 'target', 'rel'],\n span: ['class'],\n }\n\n // DOMParserでパース\n const parser = new DOMParser()\n const doc = parser.parseFromString(html, 'text/html')\n\n // ノードを再帰的にサニタイズ\n function sanitizeNode(node: Node): Node | null {\n if (node.nodeType === Node.TEXT_NODE) {\n return node.cloneNode()\n }\n\n if (node.nodeType !== Node.ELEMENT_NODE) {\n return null\n }\n\n const element = node as Element\n const tagName = element.tagName.toLowerCase()\n\n // 許可されていないタグの場合は子要素のみを返す\n if (!allowedTags.includes(tagName)) {\n const fragment = document.createDocumentFragment()\n for (const child of Array.from(element.childNodes)) {\n const sanitizedChild = sanitizeNode(child)\n if (sanitizedChild) {\n fragment.appendChild(sanitizedChild)\n }\n }\n return fragment\n }\n\n // 許可されたタグの場合は新しい要素を作成\n const newElement = document.createElement(tagName)\n\n // 許可された属性のみをコピー\n const allowedAttrs = allowedAttributes[tagName] ?? []\n for (const attr of allowedAttrs) {\n const value = element.getAttribute(attr)\n if (value !== null) {\n // href属性はjavascript:を除去\n if (attr === 'href' && value.toLowerCase().startsWith('javascript:')) {\n continue\n }\n newElement.setAttribute(attr, value)\n }\n }\n\n // aタグの場合、rel=\"noopener noreferrer\"を追加(セキュリティ対策)\n if (tagName === 'a' && newElement.getAttribute('target') === '_blank') {\n newElement.setAttribute('rel', 'noopener noreferrer')\n }\n\n // 子要素を再帰的にサニタイズ\n for (const child of Array.from(element.childNodes)) {\n const sanitizedChild = sanitizeNode(child)\n if (sanitizedChild) {\n newElement.appendChild(sanitizedChild)\n }\n }\n\n return newElement\n }\n\n // bodyの子要素をサニタイズしてHTMLに変換\n const fragment = document.createDocumentFragment()\n for (const child of Array.from(doc.body.childNodes)) {\n const sanitizedChild = sanitizeNode(child)\n if (sanitizedChild) {\n fragment.appendChild(sanitizedChild)\n }\n }\n\n const tempDiv = document.createElement('div')\n tempDiv.appendChild(fragment)\n return tempDiv.innerHTML\n}\n\n/**\n * maxLinesの値を検証\n */\nfunction isValidMaxLines(value: number): value is MaxLines {\n return Number.isInteger(value) && value >= 1 && value <= 6\n}\n\n// =============================================================================\n// LineClamp Class\n// =============================================================================\n\n/**\n * 行数制限コンポーネント\n */\nexport class LineClamp {\n private config: Required<Omit<LineClampConfig, 'isHtml' | 'tooltipDelay'>> & {\n isHtml: boolean\n tooltipDelay: number\n }\n private state: LineClampState\n private callbacks: LineClampCallbacks\n private container: HTMLElement\n private element: HTMLElement | null = null\n private textElement: HTMLElement | null = null\n private buttonContainer: HTMLElement | null = null\n private expandButton: HTMLElement | null = null\n private collapseButton: HTMLElement | null = null\n private instanceId: string\n private tooltip: Tooltip | null = null\n private resizeObserver: ResizeObserver | null = null\n private resizeDebounceTimeout: number | null = null\n\n // イベントハンドラをバインド\n private handleExpand = (): void => this.expand()\n private handleCollapse = (): void => this.collapse()\n\n constructor(\n config: LineClampConfig,\n container: HTMLElement,\n callbacks: LineClampCallbacks = {}\n ) {\n // maxLinesの検証\n if (!isValidMaxLines(config.maxLines)) {\n console.warn(`[LineClamp] Invalid maxLines value: ${config.maxLines}. Using default value 2.`)\n }\n\n this.config = {\n text: config.text,\n maxLines: isValidMaxLines(config.maxLines) ? config.maxLines : 2,\n isHtml: config.isHtml ?? false,\n showExpandButton: config.showExpandButton ?? false,\n expandButtonLabel: config.expandButtonLabel ?? 'もっと見る',\n collapseButtonLabel: config.collapseButtonLabel ?? '折りたたむ',\n showTooltip: config.showTooltip ?? true,\n tooltipPosition: config.tooltipPosition ?? 'top',\n tooltipDelay: config.tooltipDelay ?? 300,\n }\n this.container = container\n this.callbacks = callbacks\n this.instanceId = generateId('line-clamp')\n this.state = {\n text: this.config.text,\n maxLines: this.config.maxLines,\n expanded: false,\n clamped: false,\n showExpandButton: this.config.showExpandButton,\n showTooltip: this.config.showTooltip,\n tooltipPosition: this.config.tooltipPosition,\n }\n\n this.render()\n this.setupResizeObserver()\n }\n\n // ===========================================================================\n // Public Methods\n // ===========================================================================\n\n /**\n * テキストを展開\n */\n expand(): void {\n if (this.state.expanded) {\n return\n }\n\n this.state = {\n ...this.state,\n expanded: true,\n }\n\n this.element?.classList.add('expanded')\n this.element?.setAttribute('aria-expanded', 'true')\n this.updateTextStyles()\n this.updateExpandButton()\n\n this.callbacks.onExpand?.()\n this.callbacks.onToggle?.(true)\n }\n\n /**\n * テキストを折りたたむ\n */\n collapse(): void {\n if (!this.state.expanded) {\n return\n }\n\n this.state = {\n ...this.state,\n expanded: false,\n }\n\n this.element?.classList.remove('expanded')\n this.element?.setAttribute('aria-expanded', 'false')\n this.updateTextStyles()\n this.updateExpandButton()\n\n this.callbacks.onCollapse?.()\n this.callbacks.onToggle?.(false)\n }\n\n /**\n * 展開/折りたたみをトグル\n */\n toggle(): void {\n if (this.state.expanded) {\n this.collapse()\n } else {\n this.expand()\n }\n }\n\n /**\n * 展開中かどうかを取得\n * @returns {boolean} 展開中の場合true\n */\n isExpanded(): boolean {\n return this.state.expanded\n }\n\n /**\n * テキストを更新\n */\n setText(text: string): void {\n this.config = {\n ...this.config,\n text,\n }\n this.state = {\n ...this.state,\n text,\n }\n\n this.updateTextContent()\n this.updateClampedState()\n this.initializeTooltip()\n }\n\n /**\n * 最大行数を更新\n */\n setMaxLines(maxLines: MaxLines): void {\n // 入力検証\n if (!isValidMaxLines(maxLines)) {\n console.warn(`[LineClamp] Invalid maxLines value: ${maxLines}. Value must be between 1 and 6.`)\n return\n }\n\n this.config = {\n ...this.config,\n maxLines,\n }\n this.state = {\n ...this.state,\n maxLines,\n }\n\n this.updateTextStyles()\n this.updateClampedState()\n this.initializeTooltip()\n }\n\n /**\n * 現在の状態を取得\n * @returns {LineClampState} 現在の状態のコピー\n */\n getState(): LineClampState {\n return { ...this.state }\n }\n\n /**\n * テスト用:切り詰め状態を強制的に設定\n * @internal\n */\n setClampedForTesting(clamped: boolean): void {\n this.state = {\n ...this.state,\n clamped,\n }\n\n if (clamped) {\n this.element?.classList.add('clamped')\n } else {\n this.element?.classList.remove('clamped')\n }\n\n this.updateExpandButton()\n this.initializeTooltip()\n }\n\n /**\n * コンポーネントを破棄\n */\n destroy(): void {\n // デバウンスタイムアウトをクリア\n if (this.resizeDebounceTimeout !== null) {\n clearTimeout(this.resizeDebounceTimeout)\n this.resizeDebounceTimeout = null\n }\n\n // Tooltipを破棄\n if (this.tooltip) {\n this.tooltip.destroy()\n this.tooltip = null\n }\n\n // ResizeObserverを破棄\n if (this.resizeObserver) {\n this.resizeObserver.disconnect()\n this.resizeObserver = null\n }\n\n // イベントリスナーを削除\n this.cleanupButtonListeners()\n\n // DOM要素を削除\n if (this.element && this.element.parentNode) {\n this.element.parentNode.removeChild(this.element)\n }\n\n this.element = null\n this.textElement = null\n this.buttonContainer = null\n }\n\n // ===========================================================================\n // Private Methods\n // ===========================================================================\n\n /**\n * コンポーネントをレンダリング\n */\n private render(): void {\n // メインコンテナを作成\n this.element = createElement('div', {\n className: 'mokkun-line-clamp',\n attributes: {\n id: this.instanceId,\n 'aria-expanded': 'false',\n },\n })\n\n // テキスト要素を作成\n this.textElement = createElement('span', {\n className: 'line-clamp-text',\n attributes: {\n id: `${this.instanceId}-text`,\n },\n })\n\n this.updateTextContent()\n this.updateTextStyles()\n this.element.appendChild(this.textElement)\n\n // ボタンコンテナを作成\n this.buttonContainer = createElement('div', {\n className: 'line-clamp-button-container',\n })\n this.element.appendChild(this.buttonContainer)\n\n // コンテナに追加\n this.container.appendChild(this.element)\n\n // 切り詰め状態を更新(DOM追加後に実行)\n requestAnimationFrame(() => {\n this.updateClampedState()\n this.updateExpandButton()\n this.initializeTooltip()\n })\n }\n\n /**\n * テキスト内容を更新\n */\n private updateTextContent(): void {\n if (!this.textElement) {\n return\n }\n\n if (this.config.isHtml) {\n // HTMLをサニタイズしてからセット(XSS対策)\n this.textElement.innerHTML = sanitizeHtml(this.config.text)\n } else {\n this.textElement.textContent = this.config.text\n }\n }\n\n /**\n * テキストスタイルを更新\n */\n private updateTextStyles(): void {\n if (!this.textElement) {\n return\n }\n\n if (this.state.expanded) {\n // 展開時はline-clampを解除\n this.textElement.style.removeProperty('-webkit-line-clamp')\n this.textElement.style.removeProperty('display')\n this.textElement.style.removeProperty('-webkit-box-orient')\n this.textElement.style.removeProperty('overflow')\n } else {\n // 切り詰め時はline-clampを適用\n this.textElement.style.setProperty('-webkit-line-clamp', String(this.state.maxLines))\n this.textElement.style.setProperty('display', '-webkit-box')\n this.textElement.style.setProperty('-webkit-box-orient', 'vertical')\n this.textElement.style.setProperty('overflow', 'hidden')\n }\n }\n\n /**\n * 切り詰め状態を更新\n */\n private updateClampedState(): void {\n const clamped = this.checkIfClamped()\n this.state = {\n ...this.state,\n clamped,\n }\n\n if (clamped) {\n this.element?.classList.add('clamped')\n } else {\n this.element?.classList.remove('clamped')\n }\n }\n\n /**\n * テキストが切り詰められているかチェック\n */\n private checkIfClamped(): boolean {\n if (!this.textElement) {\n return false\n }\n\n // 展開中は切り詰められていないとみなす\n if (this.state.expanded) {\n return false\n }\n\n // scrollHeightとclientHeightを比較\n return this.textElement.scrollHeight > this.textElement.clientHeight\n }\n\n /**\n * ボタンのイベントリスナーをクリーンアップ\n */\n private cleanupButtonListeners(): void {\n if (this.expandButton) {\n this.expandButton.removeEventListener('click', this.handleExpand)\n this.expandButton = null\n }\n if (this.collapseButton) {\n this.collapseButton.removeEventListener('click', this.handleCollapse)\n this.collapseButton = null\n }\n }\n\n /**\n * 展開ボタンを更新\n */\n private updateExpandButton(): void {\n if (!this.buttonContainer || !this.config.showExpandButton) {\n return\n }\n\n // 既存のイベントリスナーをクリーンアップ\n this.cleanupButtonListeners()\n\n // 既存のボタンを削除\n this.buttonContainer.innerHTML = ''\n\n // 切り詰められていない場合はボタンを表示しない\n if (!this.state.clamped && !this.state.expanded) {\n return\n }\n\n if (this.state.expanded) {\n // 折りたたみボタン\n this.collapseButton = createElement('button', {\n className: 'line-clamp-collapse-button',\n textContent: this.config.collapseButtonLabel,\n attributes: {\n type: 'button',\n 'aria-controls': `${this.instanceId}-text`,\n 'aria-expanded': 'true',\n },\n })\n this.collapseButton.addEventListener('click', this.handleCollapse)\n this.buttonContainer.appendChild(this.collapseButton)\n } else {\n // 展開ボタン\n this.expandButton = createElement('button', {\n className: 'line-clamp-expand-button',\n textContent: this.config.expandButtonLabel,\n attributes: {\n type: 'button',\n 'aria-controls': `${this.instanceId}-text`,\n 'aria-expanded': 'false',\n },\n })\n this.expandButton.addEventListener('click', this.handleExpand)\n this.buttonContainer.appendChild(this.expandButton)\n }\n }\n\n /**\n * ツールチップを初期化\n */\n private initializeTooltip(): void {\n // 既存のTooltipを破棄\n if (this.tooltip) {\n this.tooltip.destroy()\n this.tooltip = null\n }\n\n // ツールチップが無効、または切り詰められていない場合は初期化しない\n if (!this.config.showTooltip || !this.element) {\n return\n }\n\n // 切り詰められている場合のみTooltipを作成(state.clampedを参照)\n if (this.state.clamped) {\n this.tooltip = new Tooltip(this.element, {\n content: this.config.isHtml\n ? sanitizeHtml(this.config.text)\n : escapeHtml(this.config.text),\n isHtml: this.config.isHtml,\n position: this.config.tooltipPosition,\n delay: this.config.tooltipDelay,\n maxWidth: '400px',\n markTrigger: false,\n })\n }\n }\n\n /**\n * ResizeObserverをセットアップ\n */\n private setupResizeObserver(): void {\n if (!this.textElement || typeof ResizeObserver === 'undefined') {\n return\n }\n\n this.resizeObserver = new ResizeObserver(() => {\n // デバウンス処理(パフォーマンス対策)\n if (this.resizeDebounceTimeout !== null) {\n clearTimeout(this.resizeDebounceTimeout)\n }\n\n this.resizeDebounceTimeout = window.setTimeout(() => {\n this.updateClampedState()\n this.updateExpandButton()\n this.initializeTooltip()\n }, 100)\n })\n\n this.resizeObserver.observe(this.textElement)\n }\n\n // ===========================================================================\n // Static Field Renderer\n // ===========================================================================\n\n static renderField(field: InputField): string {\n const lineClampField = field as InputField & {\n lines?: number\n }\n const lines = lineClampField.lines ?? 3\n\n const lineClampHtml = `\n <div class=\"mokkun-line-clamp\" style=\"-webkit-line-clamp: ${lines}; display: -webkit-box; -webkit-box-orient: vertical; overflow: hidden;\">\n ${escapeHtmlHelper(field.description ?? 'テキストコンテンツがここに表示されます。長いテキストは指定行数で切り詰められます。')}\n </div>\n `\n return createFieldWrapper(field, lineClampHtml)\n }\n}\n\n// =============================================================================\n// Factory Function\n// =============================================================================\n\n/**\n * LineClampを作成するファクトリ関数\n */\nexport function createLineClamp(\n config: LineClampConfig,\n container: HTMLElement,\n callbacks: LineClampCallbacks = {}\n): LineClamp {\n return new LineClamp(config, container, callbacks)\n}\n","/**\n * Disclosure Component\n * 開閉コンテンツコンポーネント\n *\n * \n * https://smarthr.design/products/components/disclosure/\n *\n * 機能:\n * - 開閉トリガー(クリック)\n * - スムーズなアニメーション\n * - アイコン回転\n * - デフォルト展開状態\n * - キーボード操作対応\n * - アクセシビリティ対応(ARIA属性)\n *\n * 用途:\n * - 「もっと見る」機能\n * - 補足情報の表示切り替え\n * - AccordionPanelより軽量な単独使用\n */\n\nimport { createElement, generateId } from '../utils/dom'\nimport { escapeHtml, createFieldWrapper } from '../utils/field-helpers'\nimport type { InputField } from '../../types/schema'\n\n// =============================================================================\n// Types\n// =============================================================================\n\n/**\n * Disclosureの状態\n */\nexport interface DisclosureState {\n /** 展開中かどうか */\n isOpen: boolean\n}\n\n/**\n * Disclosureのコールバック\n */\nexport interface DisclosureCallbacks {\n /** 展開時 */\n onOpen?: () => void\n /** 折りたたみ時 */\n onClose?: () => void\n /** 開閉状態変更時 */\n onChange?: (isOpen: boolean) => void\n}\n\n/**\n * Disclosureの設定\n */\nexport interface DisclosureConfig {\n /** トリガーのラベル(閉じているとき) */\n triggerLabel: string\n /** トリガーのラベル(開いているとき、オプション) */\n triggerLabelOpen?: string\n /** コンテンツ(HTML文字列またはHTMLElement) */\n content: string | HTMLElement\n /** デフォルトで展開(デフォルト: false) */\n defaultOpen?: boolean\n /** ID属性 */\n id?: string\n /** カスタムCSSクラス */\n className?: string\n /** 閉じた状態でもDOMに存在させるか(デフォルト: false) */\n visuallyHidden?: boolean\n}\n\n// =============================================================================\n// Disclosure Class\n// =============================================================================\n\n/**\n * Disclosureコンポーネント\n */\nexport class Disclosure {\n private config: DisclosureConfig\n private state: DisclosureState\n private callbacks: DisclosureCallbacks\n private container: HTMLElement\n private instanceId: string\n private triggerElement: HTMLButtonElement | null = null\n private contentWrapper: HTMLElement | null = null\n private contentElement: HTMLElement | null = null\n\n constructor(\n container: HTMLElement,\n config: DisclosureConfig,\n callbacks: DisclosureCallbacks = {}\n ) {\n this.config = config\n this.container = container\n this.callbacks = callbacks\n this.instanceId = config.id ?? generateId('disclosure')\n this.state = {\n isOpen: config.defaultOpen ?? false,\n }\n }\n\n // ===========================================================================\n // Public Methods\n // ===========================================================================\n\n /**\n * Disclosureをレンダリング\n */\n render(): void {\n this.container.innerHTML = ''\n\n this.container.className = [\n 'mokkun-disclosure',\n this.state.isOpen ? 'is-open' : '',\n this.config.className ?? '',\n ]\n .filter(Boolean)\n .join(' ')\n\n this.container.id = this.instanceId\n\n // トリガーボタン\n this.triggerElement = this.renderTrigger()\n this.container.appendChild(this.triggerElement)\n\n // コンテンツ\n this.contentWrapper = this.renderContent()\n this.container.appendChild(this.contentWrapper)\n }\n\n /**\n * 展開する\n */\n open(): void {\n if (this.state.isOpen) {\n return\n }\n\n this.state = {\n ...this.state,\n isOpen: true,\n }\n\n this.updateUI()\n this.callbacks.onOpen?.()\n this.callbacks.onChange?.(true)\n }\n\n /**\n * 折りたたむ\n */\n close(): void {\n if (!this.state.isOpen) {\n return\n }\n\n this.state = {\n ...this.state,\n isOpen: false,\n }\n\n this.updateUI()\n this.callbacks.onClose?.()\n this.callbacks.onChange?.(false)\n }\n\n /**\n * 開閉を切り替え\n */\n toggle(): void {\n if (this.state.isOpen) {\n this.close()\n } else {\n this.open()\n }\n }\n\n /**\n * 展開状態を確認\n */\n isOpen(): boolean {\n return this.state.isOpen\n }\n\n /**\n * 現在の状態を取得\n */\n getState(): DisclosureState {\n return { ...this.state }\n }\n\n /**\n * コンテンツを更新\n */\n setContent(content: string | HTMLElement): void {\n this.config = {\n ...this.config,\n content,\n }\n\n if (this.contentElement) {\n this.contentElement.innerHTML = ''\n if (typeof content === 'string') {\n this.contentElement.innerHTML = content\n } else {\n this.contentElement.appendChild(content)\n }\n }\n }\n\n /**\n * トリガーラベルを更新\n */\n setTriggerLabel(label: string, labelOpen?: string): void {\n this.config = {\n ...this.config,\n triggerLabel: label,\n triggerLabelOpen: labelOpen,\n }\n\n if (this.triggerElement) {\n const labelEl = this.triggerElement.querySelector('.disclosure-trigger-label')\n if (labelEl) {\n labelEl.textContent = this.getCurrentLabel()\n }\n }\n }\n\n /**\n * コンポーネントを破棄\n */\n destroy(): void {\n this.container.innerHTML = ''\n this.triggerElement = null\n this.contentWrapper = null\n this.contentElement = null\n }\n\n // ===========================================================================\n // Private Methods - Rendering\n // ===========================================================================\n\n private renderTrigger(): HTMLButtonElement {\n const triggerId = `${this.instanceId}-trigger`\n const contentId = `${this.instanceId}-content`\n\n const trigger = document.createElement('button')\n trigger.type = 'button'\n trigger.className = 'disclosure-trigger'\n trigger.id = triggerId\n trigger.setAttribute('aria-expanded', String(this.state.isOpen))\n trigger.setAttribute('aria-controls', contentId)\n\n // アイコン\n const icon = this.renderIcon()\n trigger.appendChild(icon)\n\n // ラベル\n const label = createElement('span', {\n className: 'disclosure-trigger-label',\n textContent: this.getCurrentLabel(),\n })\n trigger.appendChild(label)\n\n // クリックイベント\n trigger.addEventListener('click', () => {\n this.toggle()\n })\n\n // キーボードイベント\n trigger.addEventListener('keydown', (event) => {\n if (event.key === 'Enter' || event.key === ' ') {\n event.preventDefault()\n this.toggle()\n }\n })\n\n return trigger\n }\n\n private renderIcon(): HTMLElement {\n const icon = createElement('span', {\n className: `disclosure-icon${this.state.isOpen ? ' is-open' : ''}`,\n attributes: {\n 'aria-hidden': 'true',\n },\n })\n\n // キャレットアイコン(右向き矢印、展開時に90度回転して下向きに)\n const svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg')\n svg.setAttribute('width', '16')\n svg.setAttribute('height', '16')\n svg.setAttribute('viewBox', '0 0 16 16')\n svg.setAttribute('fill', 'currentColor')\n\n const path = document.createElementNS('http://www.w3.org/2000/svg', 'path')\n path.setAttribute('d', 'M6 3l5 5-5 5V3z')\n\n svg.appendChild(path)\n icon.appendChild(svg)\n\n return icon\n }\n\n private renderContent(): HTMLElement {\n const contentId = `${this.instanceId}-content`\n const triggerId = `${this.instanceId}-trigger`\n\n const wrapper = createElement('div', {\n className: `disclosure-content-wrapper${this.state.isOpen ? ' is-open' : ''}`,\n })\n\n this.contentElement = createElement('div', {\n className: 'disclosure-content',\n attributes: {\n id: contentId,\n role: 'region',\n 'aria-labelledby': triggerId,\n },\n })\n\n // 閉じている場合の処理\n if (!this.state.isOpen) {\n if (this.config.visuallyHidden) {\n // DOMに存在させるが視覚的に隠す\n this.contentElement.setAttribute('aria-hidden', 'true')\n } else {\n // DOMから完全に非表示\n this.contentElement.setAttribute('hidden', '')\n }\n }\n\n // コンテンツを追加\n if (typeof this.config.content === 'string') {\n this.contentElement.innerHTML = this.config.content\n } else {\n this.contentElement.appendChild(this.config.content)\n }\n\n wrapper.appendChild(this.contentElement)\n\n return wrapper\n }\n\n // ===========================================================================\n // Private Methods - State Updates\n // ===========================================================================\n\n private updateUI(): void {\n // コンテナのクラス更新\n if (this.state.isOpen) {\n this.container.classList.add('is-open')\n } else {\n this.container.classList.remove('is-open')\n }\n\n // トリガーの更新\n if (this.triggerElement) {\n this.triggerElement.setAttribute('aria-expanded', String(this.state.isOpen))\n\n // ラベルの更新\n const labelEl = this.triggerElement.querySelector('.disclosure-trigger-label')\n if (labelEl) {\n labelEl.textContent = this.getCurrentLabel()\n }\n\n // アイコンの更新\n const icon = this.triggerElement.querySelector('.disclosure-icon')\n if (icon) {\n if (this.state.isOpen) {\n icon.classList.add('is-open')\n } else {\n icon.classList.remove('is-open')\n }\n }\n }\n\n // コンテンツラッパーの更新\n if (this.contentWrapper) {\n if (this.state.isOpen) {\n this.contentWrapper.classList.add('is-open')\n } else {\n this.contentWrapper.classList.remove('is-open')\n }\n }\n\n // コンテンツの更新\n if (this.contentElement) {\n if (this.state.isOpen) {\n this.contentElement.removeAttribute('hidden')\n this.contentElement.removeAttribute('aria-hidden')\n } else {\n if (this.config.visuallyHidden) {\n this.contentElement.setAttribute('aria-hidden', 'true')\n } else {\n // アニメーション終了後にhiddenを設定\n setTimeout(() => {\n if (!this.state.isOpen && this.contentElement) {\n this.contentElement.setAttribute('hidden', '')\n }\n }, 200) // アニメーション時間に合わせる\n }\n }\n }\n }\n\n private getCurrentLabel(): string {\n if (this.state.isOpen && this.config.triggerLabelOpen) {\n return this.config.triggerLabelOpen\n }\n return this.config.triggerLabel\n }\n\n // ===========================================================================\n // Static Field Renderer\n // ===========================================================================\n\n static renderField(field: InputField): string {\n const disclosureHtml = `\n <details class=\"mokkun-disclosure\">\n <summary class=\"disclosure-trigger\">${escapeHtml(field.label)}</summary>\n <div class=\"disclosure-content\">\n <p>${escapeHtml(field.description ?? '詳細コンテンツがここに表示されます')}</p>\n </div>\n </details>\n `\n return createFieldWrapper(field, disclosureHtml)\n }\n}\n\n// =============================================================================\n// Factory Function\n// =============================================================================\n\n/**\n * Disclosureを作成\n */\nexport function createDisclosure(\n container: HTMLElement,\n config: DisclosureConfig,\n callbacks?: DisclosureCallbacks\n): Disclosure {\n const disclosure = new Disclosure(container, config, callbacks)\n disclosure.render()\n return disclosure\n}\n","/**\n * AccordionPanel Component\n * 折りたたみパネルコンポーネント\n *\n * \n * - 複数パネルの同時開閉制御(単一/複数展開モード)\n * - 開閉アニメーション\n * - アイコン付きヘッダー\n * - デフォルト展開状態の設定\n * - キーボード操作対応\n * - アクセシビリティ対応(ARIA属性)\n */\n\nimport { createElement, generateId } from '../utils/dom'\nimport { escapeHtml, createFieldWrapper } from '../utils/field-helpers'\nimport type { InputField } from '../../types/schema'\n\n// =============================================================================\n// Types\n// =============================================================================\n\n/**\n * アコーディオンアイテムの定義\n */\nexport interface AccordionItem {\n /** 一意な識別子 */\n name: string\n /** ヘッダーテキスト */\n title: string\n /** ヘッダーアイコン(オプション) */\n icon?: string\n /** コンテンツ(HTML文字列またはHTMLElement) */\n content: string | HTMLElement\n /** 無効化 */\n disabled?: boolean\n}\n\n/**\n * アイコンの配置位置\n */\nexport type IconPosition = 'left' | 'right'\n\n/**\n * 見出しタイプ\n */\nexport type HeadingType = 'sectionTitle' | 'blockTitle' | 'subBlockTitle' | 'subSubBlockTitle'\n\n/**\n * アコーディオンパネルの状態\n */\nexport interface AccordionPanelState {\n /** 展開中のパネル名リスト */\n expandedItems: string[]\n /** フォーカスされているアイテムのインデックス */\n focusedIndex: number\n}\n\n/**\n * アコーディオンパネルのコールバック\n */\nexport interface AccordionPanelCallbacks {\n /** パネル展開時 */\n onExpand?: (name: string) => void\n /** パネル折りたたみ時 */\n onCollapse?: (name: string) => void\n /** 展開状態変更時 */\n onChange?: (expandedItems: string[]) => void\n}\n\n/**\n * アコーディオンパネルの設定\n */\nexport interface AccordionPanelConfig {\n /** アコーディオンアイテム */\n items: AccordionItem[]\n /** 複数パネル同時展開を許可(デフォルト: true) */\n expandableMultiply?: boolean\n /** デフォルトで展開するパネル名のリスト */\n defaultExpanded?: string[]\n /** アイコンの配置位置(デフォルト: left) */\n iconPosition?: IconPosition\n /** 見出しタイプ(デフォルト: blockTitle) */\n headingType?: HeadingType\n /** ID属性 */\n id?: string\n /** カスタムCSSクラス */\n className?: string\n}\n\n// =============================================================================\n// AccordionPanel Class\n// =============================================================================\n\n/**\n * アコーディオンパネルコンポーネント\n */\nexport class AccordionPanel {\n private config: AccordionPanelConfig\n private state: AccordionPanelState\n private callbacks: AccordionPanelCallbacks\n private container: HTMLElement\n private instanceId: string\n private itemElements: Map<string, { trigger: HTMLElement; content: HTMLElement }> = new Map()\n\n constructor(\n container: HTMLElement,\n config: AccordionPanelConfig,\n callbacks: AccordionPanelCallbacks = {}\n ) {\n this.config = config\n this.container = container\n this.callbacks = callbacks\n this.instanceId = config.id ?? generateId('accordion')\n this.state = this.createInitialState()\n }\n\n // ===========================================================================\n // Public Methods\n // ===========================================================================\n\n /**\n * アコーディオンパネルをレンダリング\n */\n render(): void {\n this.container.innerHTML = ''\n this.itemElements.clear()\n\n const iconPosition = this.config.iconPosition ?? 'left'\n const headingType = this.config.headingType ?? 'blockTitle'\n\n this.container.className = [\n 'mokkun-accordion-panel',\n `accordion-icon-${iconPosition}`,\n `accordion-heading-${headingType}`,\n this.config.className ?? '',\n ]\n .filter(Boolean)\n .join(' ')\n\n this.container.setAttribute('role', 'region')\n this.container.id = this.instanceId\n\n // アイテムをレンダリング\n this.config.items.forEach((item, index) => {\n const itemElement = this.renderItem(item, index)\n this.container.appendChild(itemElement)\n })\n\n // キーボードイベントをアタッチ\n this.attachKeyboardEvents()\n }\n\n /**\n * パネルを展開\n */\n expand(name: string): void {\n const item = this.config.items.find((i) => i.name === name)\n if (!item || item.disabled) {\n return\n }\n\n if (this.state.expandedItems.includes(name)) {\n return\n }\n\n const expandableMultiply = this.config.expandableMultiply ?? true\n const previouslyExpanded = [...this.state.expandedItems]\n\n if (expandableMultiply) {\n this.state = {\n ...this.state,\n expandedItems: [...this.state.expandedItems, name],\n }\n } else {\n // 単一展開モード: 他のパネルを閉じる\n this.state = {\n ...this.state,\n expandedItems: [name],\n }\n\n // 以前展開していたパネルのUIを閉じる\n previouslyExpanded.forEach((prevName) => {\n if (prevName !== name) {\n this.updateItemState(prevName, false)\n this.callbacks.onCollapse?.(prevName)\n }\n })\n }\n\n this.updateItemState(name, true)\n this.callbacks.onExpand?.(name)\n this.callbacks.onChange?.(this.state.expandedItems)\n }\n\n /**\n * パネルを折りたたむ\n */\n collapse(name: string): void {\n if (!this.state.expandedItems.includes(name)) {\n return\n }\n\n this.state = {\n ...this.state,\n expandedItems: this.state.expandedItems.filter((n) => n !== name),\n }\n\n this.updateItemState(name, false)\n this.callbacks.onCollapse?.(name)\n this.callbacks.onChange?.(this.state.expandedItems)\n }\n\n /**\n * パネルの展開/折りたたみを切り替え\n */\n toggle(name: string): void {\n if (this.state.expandedItems.includes(name)) {\n this.collapse(name)\n } else {\n this.expand(name)\n }\n }\n\n /**\n * すべてのパネルを展開\n */\n expandAll(): void {\n if (!(this.config.expandableMultiply ?? true)) {\n return\n }\n\n const enabledItems = this.config.items\n .filter((item) => !item.disabled)\n .map((item) => item.name)\n\n this.state = {\n ...this.state,\n expandedItems: enabledItems,\n }\n\n enabledItems.forEach((name) => {\n this.updateItemState(name, true)\n })\n\n this.callbacks.onChange?.(this.state.expandedItems)\n }\n\n /**\n * すべてのパネルを折りたたむ\n */\n collapseAll(): void {\n const previousExpanded = [...this.state.expandedItems]\n\n this.state = {\n ...this.state,\n expandedItems: [],\n }\n\n previousExpanded.forEach((name) => {\n this.updateItemState(name, false)\n })\n\n this.callbacks.onChange?.(this.state.expandedItems)\n }\n\n /**\n * パネルの展開状態を確認\n */\n isExpanded(name: string): boolean {\n return this.state.expandedItems.includes(name)\n }\n\n /**\n * 現在の状態を取得\n */\n getState(): AccordionPanelState {\n return { ...this.state }\n }\n\n /**\n * アイテムを更新\n */\n setItems(items: AccordionItem[]): void {\n this.config = {\n ...this.config,\n items,\n }\n\n // 存在しないアイテムを展開状態から削除\n const validNames = items.map((item) => item.name)\n this.state = {\n ...this.state,\n expandedItems: this.state.expandedItems.filter((name) => validNames.includes(name)),\n focusedIndex: Math.min(this.state.focusedIndex, items.length - 1),\n }\n\n this.render()\n }\n\n /**\n * コンポーネントを破棄\n */\n destroy(): void {\n this.container.innerHTML = ''\n this.itemElements.clear()\n }\n\n // ===========================================================================\n // Private Methods - Initialization\n // ===========================================================================\n\n private createInitialState(): AccordionPanelState {\n const defaultExpanded = this.config.defaultExpanded ?? []\n const expandableMultiply = this.config.expandableMultiply ?? true\n\n // 単一展開モードの場合、最初の一つのみ展開\n const expandedItems = expandableMultiply\n ? defaultExpanded.filter((name) => {\n const item = this.config.items.find((i) => i.name === name)\n return item && !item.disabled\n })\n : defaultExpanded.slice(0, 1).filter((name) => {\n const item = this.config.items.find((i) => i.name === name)\n return item && !item.disabled\n })\n\n return {\n expandedItems,\n focusedIndex: -1,\n }\n }\n\n // ===========================================================================\n // Private Methods - Rendering\n // ===========================================================================\n\n private renderItem(item: AccordionItem, index: number): HTMLElement {\n const isExpanded = this.state.expandedItems.includes(item.name)\n const triggerId = `${this.instanceId}-trigger-${item.name}`\n const contentId = `${this.instanceId}-content-${item.name}`\n\n const itemWrapper = createElement('div', {\n className: `accordion-item${item.disabled ? ' is-disabled' : ''}${isExpanded ? ' is-expanded' : ''}`,\n attributes: {\n 'data-name': item.name,\n 'data-index': String(index),\n },\n })\n\n // ヘッダー(トリガー)\n const trigger = this.renderTrigger(item, isExpanded, triggerId, contentId)\n itemWrapper.appendChild(trigger)\n\n // コンテンツパネル\n const content = this.renderContent(item, isExpanded, contentId, triggerId)\n itemWrapper.appendChild(content)\n\n // 要素を保存\n this.itemElements.set(item.name, { trigger, content })\n\n return itemWrapper\n }\n\n private renderTrigger(\n item: AccordionItem,\n isExpanded: boolean,\n triggerId: string,\n contentId: string\n ): HTMLElement {\n const iconPosition = this.config.iconPosition ?? 'left'\n\n const trigger = createElement('button', {\n className: 'accordion-trigger',\n attributes: {\n type: 'button',\n id: triggerId,\n 'aria-expanded': String(isExpanded),\n 'aria-controls': contentId,\n 'aria-disabled': item.disabled ? 'true' : 'false',\n tabindex: item.disabled ? '-1' : '0',\n },\n })\n\n // アイコン(左配置の場合)\n if (iconPosition === 'left') {\n const icon = this.renderIcon(isExpanded, iconPosition)\n trigger.appendChild(icon)\n }\n\n // タイトルアイコン(ユーザー指定)\n if (item.icon) {\n const titleIcon = createElement('span', {\n className: 'accordion-trigger-title-icon',\n })\n titleIcon.innerHTML = item.icon\n trigger.appendChild(titleIcon)\n }\n\n // タイトルテキスト\n const title = createElement('span', {\n className: 'accordion-trigger-title',\n textContent: item.title,\n })\n trigger.appendChild(title)\n\n // アイコン(右配置の場合)\n if (iconPosition === 'right') {\n const icon = this.renderIcon(isExpanded, iconPosition)\n trigger.appendChild(icon)\n }\n\n // クリックイベント\n if (!item.disabled) {\n trigger.addEventListener('click', () => {\n this.toggle(item.name)\n })\n }\n\n return trigger\n }\n\n private renderIcon(isExpanded: boolean, position: IconPosition): HTMLElement {\n const icon = createElement('span', {\n className: `accordion-icon accordion-icon-${position}${isExpanded ? ' is-expanded' : ''}`,\n attributes: {\n 'aria-hidden': 'true',\n },\n })\n\n // キャレットアイコン\n const svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg')\n svg.setAttribute('width', '16')\n svg.setAttribute('height', '16')\n svg.setAttribute('viewBox', '0 0 16 16')\n svg.setAttribute('fill', 'currentColor')\n\n const path = document.createElementNS('http://www.w3.org/2000/svg', 'path')\n\n if (position === 'left') {\n // 右向き矢印 → 展開時に90度回転して下向きに\n path.setAttribute('d', 'M6 3l5 5-5 5V3z')\n } else {\n // 下向き矢印 → 展開時に180度回転して上向きに\n path.setAttribute('d', 'M3 6l5 5 5-5H3z')\n }\n\n svg.appendChild(path)\n icon.appendChild(svg)\n\n return icon\n }\n\n private renderContent(\n item: AccordionItem,\n isExpanded: boolean,\n contentId: string,\n triggerId: string\n ): HTMLElement {\n const wrapper = createElement('div', {\n className: `accordion-content-wrapper${isExpanded ? ' is-expanded' : ''}`,\n })\n\n const content = createElement('div', {\n className: 'accordion-content',\n attributes: {\n id: contentId,\n role: 'region',\n 'aria-labelledby': triggerId,\n },\n })\n\n if (!isExpanded) {\n content.setAttribute('hidden', '')\n }\n\n // コンテンツを追加\n if (typeof item.content === 'string') {\n content.innerHTML = item.content\n } else {\n content.appendChild(item.content)\n }\n\n wrapper.appendChild(content)\n\n return wrapper\n }\n\n // ===========================================================================\n // Private Methods - State Updates\n // ===========================================================================\n\n private updateItemState(name: string, isExpanded: boolean): void {\n const elements = this.itemElements.get(name)\n if (!elements) {\n return\n }\n\n const { trigger, content } = elements\n const itemWrapper = trigger.parentElement\n\n // トリガーの状態更新\n trigger.setAttribute('aria-expanded', String(isExpanded))\n\n // アイコンの状態更新\n const icon = trigger.querySelector('.accordion-icon')\n if (icon) {\n if (isExpanded) {\n icon.classList.add('is-expanded')\n } else {\n icon.classList.remove('is-expanded')\n }\n }\n\n // ラッパーの状態更新\n if (isExpanded) {\n itemWrapper?.classList.add('is-expanded')\n content.classList.add('is-expanded')\n } else {\n itemWrapper?.classList.remove('is-expanded')\n content.classList.remove('is-expanded')\n }\n\n // コンテンツパネルの表示/非表示\n const contentPanel = content.querySelector('.accordion-content')\n if (contentPanel) {\n if (isExpanded) {\n contentPanel.removeAttribute('hidden')\n } else {\n // アニメーション終了後にhiddenを設定\n setTimeout(() => {\n if (!this.state.expandedItems.includes(name)) {\n contentPanel.setAttribute('hidden', '')\n }\n }, 200) // アニメーション時間に合わせる\n }\n }\n }\n\n // ===========================================================================\n // Private Methods - Keyboard Navigation\n // ===========================================================================\n\n private attachKeyboardEvents(): void {\n this.container.addEventListener('keydown', (event) => {\n const target = event.target as HTMLElement\n\n if (!target.classList.contains('accordion-trigger')) {\n return\n }\n\n const currentIndex = parseInt(target.closest('.accordion-item')?.getAttribute('data-index') ?? '-1', 10)\n\n switch (event.key) {\n case 'ArrowDown':\n event.preventDefault()\n this.focusNextItem(currentIndex)\n break\n\n case 'ArrowUp':\n event.preventDefault()\n this.focusPreviousItem(currentIndex)\n break\n\n case 'Home':\n event.preventDefault()\n this.focusFirstItem()\n break\n\n case 'End':\n event.preventDefault()\n this.focusLastItem()\n break\n\n case 'Enter':\n case ' ':\n // クリックイベントで処理されるため、ここでは何もしない\n break\n }\n })\n }\n\n private focusNextItem(currentIndex: number): void {\n const enabledItems = this.config.items\n .map((item, index) => ({ item, index }))\n .filter(({ item }) => !item.disabled)\n\n const currentEnabledIndex = enabledItems.findIndex(({ index }) => index === currentIndex)\n const nextEnabledIndex = (currentEnabledIndex + 1) % enabledItems.length\n const nextItem = enabledItems[nextEnabledIndex]\n\n if (nextItem) {\n this.focusItem(nextItem.item.name)\n }\n }\n\n private focusPreviousItem(currentIndex: number): void {\n const enabledItems = this.config.items\n .map((item, index) => ({ item, index }))\n .filter(({ item }) => !item.disabled)\n\n const currentEnabledIndex = enabledItems.findIndex(({ index }) => index === currentIndex)\n const previousEnabledIndex = currentEnabledIndex <= 0 ? enabledItems.length - 1 : currentEnabledIndex - 1\n const previousItem = enabledItems[previousEnabledIndex]\n\n if (previousItem) {\n this.focusItem(previousItem.item.name)\n }\n }\n\n private focusFirstItem(): void {\n const firstEnabled = this.config.items.find((item) => !item.disabled)\n if (firstEnabled) {\n this.focusItem(firstEnabled.name)\n }\n }\n\n private focusLastItem(): void {\n const enabledItems = this.config.items.filter((item) => !item.disabled)\n const lastEnabled = enabledItems[enabledItems.length - 1]\n if (lastEnabled) {\n this.focusItem(lastEnabled.name)\n }\n }\n\n private focusItem(name: string): void {\n const elements = this.itemElements.get(name)\n if (elements) {\n elements.trigger.focus()\n }\n }\n\n // ===========================================================================\n // Static Field Renderer\n // ===========================================================================\n\n static renderField(field: InputField): string {\n const accordionHtml = `\n <div class=\"mokkun-accordion\">\n <div class=\"accordion-item\">\n <button type=\"button\" class=\"accordion-trigger\" aria-expanded=\"false\">\n <span>${escapeHtml(field.label)}</span>\n <span class=\"accordion-icon\">▼</span>\n </button>\n <div class=\"accordion-content\" hidden>\n <p>${escapeHtml(field.description ?? 'アコーディオンコンテンツ')}</p>\n </div>\n </div>\n </div>\n `\n return createFieldWrapper(field, accordionHtml)\n }\n}\n\n// =============================================================================\n// Factory Function\n// =============================================================================\n\n/**\n * アコーディオンパネルを作成\n */\nexport function createAccordionPanel(\n container: HTMLElement,\n config: AccordionPanelConfig,\n callbacks?: AccordionPanelCallbacks\n): AccordionPanel {\n const accordion = new AccordionPanel(container, config, callbacks)\n accordion.render()\n return accordion\n}\n","/**\n * Section Navigation Component\n * セクション間をスムーズスクロールで移動するナビゲーション\n */\n\nimport { createElement, clearElement } from '../utils/dom'\nimport { escapeHtml, createFieldWrapper } from '../utils/field-helpers'\nimport type { InputField } from '../../types/schema'\n\n// =============================================================================\n// Constants\n// =============================================================================\n\n/** Default scroll offset to account for sticky headers */\nconst DEFAULT_SCROLL_OFFSET = 80\n\n/** Delay after scroll before resuming intersection observer updates */\nconst SCROLL_DEBOUNCE_MS = 1000\n\n/**\n * Default root margin for intersection observer.\n * Top -20%: triggers slightly before section reaches top\n * Bottom -60%: section must be in upper 40% of viewport to be \"active\"\n */\nconst DEFAULT_ROOT_MARGIN = '-20% 0px -60% 0px'\n\n// =============================================================================\n// Types\n// =============================================================================\n\n/**\n * セクション定義\n */\nexport interface SectionDefinition {\n /** セクションID(HTMLのid属性と一致させる) */\n id: string\n /** セクション名 */\n label: string\n /** アイコン(絵文字のみサポート、HTMLは安全のためテキストとして表示) */\n icon?: string\n /** 無効化 */\n disabled?: boolean\n}\n\n/**\n * セクションナビの状態\n */\nexport interface SectionNavState {\n /** 現在アクティブなセクションID */\n activeSectionId: string\n /** セクション一覧 */\n sections: SectionDefinition[]\n}\n\n/**\n * セクションナビのコールバック\n */\nexport interface SectionNavCallbacks {\n /** セクション変更時(クリックによる遷移) */\n onSectionChange?: (sectionId: string, state: SectionNavState) => void\n /** スクロールによるアクティブセクション変更時 */\n onActiveChange?: (sectionId: string, state: SectionNavState) => void\n}\n\n/**\n * セクションナビの設定\n */\nexport interface SectionNavConfig {\n /** セクション一覧 */\n sections: SectionDefinition[]\n /** 初期アクティブセクションID */\n defaultActiveSection?: string\n /** スクロールオフセット(sticky headerの高さ考慮) */\n scrollOffset?: number\n /** スクロール動作 */\n scrollBehavior?: ScrollBehavior\n /** モバイル表示モード */\n mobileMode?: 'scroll' | 'dropdown'\n /** スティッキー位置(top値) */\n stickyTop?: string\n /** Intersection Observer のルートマージン */\n rootMargin?: string\n /** Intersection Observer の閾値 */\n threshold?: number | number[]\n}\n\n// =============================================================================\n// SectionNav Class\n// =============================================================================\n\n/**\n * セクションナビゲーションコンポーネント\n */\nexport class SectionNav {\n private config: SectionNavConfig\n private state: SectionNavState\n private callbacks: SectionNavCallbacks\n private container: HTMLElement\n private observer: IntersectionObserver | null = null\n private isScrolling = false\n private scrollTimeout: number | null = null\n private documentClickHandler: ((e: MouseEvent) => void) | null = null\n\n constructor(\n config: SectionNavConfig,\n container: HTMLElement,\n callbacks: SectionNavCallbacks = {}\n ) {\n this.validateConfig(config, container)\n this.config = config\n this.container = container\n this.callbacks = callbacks\n this.state = this.createInitialState()\n }\n\n // ===========================================================================\n // Public Methods\n // ===========================================================================\n\n /**\n * ナビゲーションをレンダリング\n */\n render(): void {\n clearElement(this.container)\n\n const mobileMode = this.config.mobileMode ?? 'scroll'\n const stickyTop = this.config.stickyTop ?? '0'\n\n this.container.className = `mokkun-section-nav section-nav-${mobileMode}`\n this.container.style.display = 'block'\n this.container.style.position = 'sticky'\n this.container.style.top = stickyTop\n this.container.style.zIndex = '100'\n\n const wrapper = createElement('div', { className: 'section-nav-wrapper' })\n\n // ナビゲーションリスト\n const navList = this.renderNavList()\n wrapper.appendChild(navList)\n\n // モバイル用ドロップダウン(mobileMode === 'dropdown'の場合)\n if (mobileMode === 'dropdown') {\n const dropdown = this.renderMobileDropdown()\n wrapper.appendChild(dropdown)\n }\n\n this.container.appendChild(wrapper)\n\n // Intersection Observerをセットアップ\n this.setupIntersectionObserver()\n }\n\n /**\n * 指定セクションにスクロール\n * @param sectionId - スクロール先のセクションID\n */\n scrollToSection(sectionId: string): void {\n const section = this.state.sections.find(s => s.id === sectionId)\n if (!section || section.disabled) {\n return\n }\n\n const targetElement = document.getElementById(sectionId)\n if (!targetElement) {\n return\n }\n\n // スクロール中フラグを設定(Intersection Observerの誤検知防止)\n this.isScrolling = true\n\n const offset = this.config.scrollOffset ?? DEFAULT_SCROLL_OFFSET\n const behavior = this.config.scrollBehavior ?? 'smooth'\n\n const targetPosition = targetElement.getBoundingClientRect().top + window.scrollY - offset\n\n window.scrollTo({\n top: targetPosition,\n behavior,\n })\n\n // 状態を更新\n this.state = {\n ...this.state,\n activeSectionId: sectionId,\n }\n\n this.updateActiveStyles()\n this.callbacks.onSectionChange?.(sectionId, this.getState())\n\n // スクロール完了後にフラグをリセット\n if (this.scrollTimeout !== null) {\n window.clearTimeout(this.scrollTimeout)\n }\n this.scrollTimeout = window.setTimeout(() => {\n this.isScrolling = false\n }, SCROLL_DEBOUNCE_MS)\n }\n\n /**\n * アクティブセクションを設定(スクロールなし)\n * @param sectionId - アクティブにするセクションID\n */\n setActiveSection(sectionId: string): void {\n const section = this.state.sections.find(s => s.id === sectionId)\n if (!section || section.disabled) {\n return\n }\n\n this.state = {\n ...this.state,\n activeSectionId: sectionId,\n }\n\n this.updateActiveStyles()\n }\n\n /**\n * 現在の状態を取得\n * @returns 現在の状態のコピー\n */\n getState(): SectionNavState {\n return {\n ...this.state,\n sections: this.state.sections.map(s => ({ ...s })),\n }\n }\n\n /**\n * 現在のアクティブセクションを取得\n * @returns アクティブなセクション定義、またはundefined\n */\n getActiveSection(): SectionDefinition | undefined {\n return this.state.sections.find(s => s.id === this.state.activeSectionId)\n }\n\n /**\n * セクションを追加\n * @param section - 追加するセクション定義\n * @param index - 挿入位置(省略時は末尾に追加)\n */\n addSection(section: SectionDefinition, index?: number): void {\n const newSections = [...this.state.sections]\n if (index !== undefined && index >= 0 && index <= newSections.length) {\n newSections.splice(index, 0, section)\n } else {\n newSections.push(section)\n }\n\n this.state = {\n ...this.state,\n sections: newSections,\n }\n\n this.render()\n }\n\n /**\n * セクションを削除\n * @param sectionId - 削除するセクションID\n * @returns 削除成功時true\n */\n removeSection(sectionId: string): boolean {\n const index = this.state.sections.findIndex(s => s.id === sectionId)\n if (index === -1) {\n return false\n }\n\n const newSections = this.state.sections.filter(s => s.id !== sectionId)\n\n let newActiveSectionId = this.state.activeSectionId\n if (this.state.activeSectionId === sectionId && newSections.length > 0) {\n const enabledSection = newSections.find(s => !s.disabled)\n newActiveSectionId = enabledSection?.id ?? newSections[0].id\n }\n\n this.state = {\n ...this.state,\n sections: newSections,\n activeSectionId: newActiveSectionId,\n }\n\n this.render()\n return true\n }\n\n /**\n * セクションを更新\n * @param sectionId - 更新するセクションID\n * @param updates - 更新内容\n * @returns 更新成功時true\n */\n updateSection(sectionId: string, updates: Partial<SectionDefinition>): boolean {\n const index = this.state.sections.findIndex(s => s.id === sectionId)\n if (index === -1) {\n return false\n }\n\n this.state = {\n ...this.state,\n sections: this.state.sections.map(s =>\n s.id === sectionId ? { ...s, ...updates } : s\n ),\n }\n\n this.render()\n return true\n }\n\n /**\n * クリーンアップ(Intersection Observerとイベントリスナーの解除)\n */\n destroy(): void {\n if (this.observer) {\n this.observer.disconnect()\n this.observer = null\n }\n if (this.scrollTimeout !== null) {\n window.clearTimeout(this.scrollTimeout)\n this.scrollTimeout = null\n }\n if (this.documentClickHandler) {\n document.removeEventListener('click', this.documentClickHandler)\n this.documentClickHandler = null\n }\n }\n\n // ===========================================================================\n // Private Methods - Validation\n // ===========================================================================\n\n /**\n * 設定を検証\n */\n private validateConfig(config: SectionNavConfig, container: HTMLElement): void {\n if (!config?.sections || !Array.isArray(config.sections)) {\n throw new Error('SectionNav: config.sections must be an array')\n }\n if (!(container instanceof HTMLElement)) {\n throw new Error('SectionNav: container must be an HTMLElement')\n }\n if (config.sections.length === 0) {\n throw new Error('SectionNav: config.sections must not be empty')\n }\n\n for (const section of config.sections) {\n if (!section.id || typeof section.id !== 'string') {\n throw new Error('SectionNav: Each section must have a valid id')\n }\n if (!section.label || typeof section.label !== 'string') {\n throw new Error(`SectionNav: Section \"${section.id}\" must have a valid label`)\n }\n }\n }\n\n // ===========================================================================\n // Private Methods - Rendering\n // ===========================================================================\n\n /**\n * 初期状態を作成\n */\n private createInitialState(): SectionNavState {\n const defaultActiveSection = this.config.defaultActiveSection\n ?? this.config.sections.find(s => !s.disabled)?.id\n ?? this.config.sections[0]?.id\n ?? ''\n\n return {\n activeSectionId: defaultActiveSection,\n sections: [...this.config.sections],\n }\n }\n\n /**\n * ナビゲーションリストをレンダリング\n */\n private renderNavList(): HTMLElement {\n const navList = createElement('nav', {\n className: 'section-nav-list',\n attributes: {\n 'aria-label': 'セクションナビゲーション',\n role: 'navigation',\n },\n })\n\n const ul = createElement('ul', {\n className: 'section-nav-items',\n attributes: { role: 'list' },\n })\n\n for (const section of this.state.sections) {\n const item = this.renderNavItem(section)\n ul.appendChild(item)\n }\n\n navList.appendChild(ul)\n return navList\n }\n\n /**\n * ナビゲーションアイテムをレンダリング\n */\n private renderNavItem(section: SectionDefinition): HTMLElement {\n const isActive = section.id === this.state.activeSectionId\n const className = [\n 'section-nav-item',\n isActive ? 'active' : '',\n section.disabled ? 'disabled' : '',\n ].filter(Boolean).join(' ')\n\n const li = createElement('li', { className })\n\n const button = createElement('button', {\n className: 'section-nav-button',\n attributes: {\n type: 'button',\n 'aria-current': isActive ? 'location' : '',\n 'data-section-id': section.id,\n },\n })\n\n // aria-currentが空の場合は属性を削除\n if (!isActive) {\n button.removeAttribute('aria-current')\n }\n\n if (section.disabled) {\n button.setAttribute('aria-disabled', 'true')\n button.setAttribute('disabled', 'true')\n }\n\n // アイコン(XSS防止のためtextContentを使用)\n if (section.icon) {\n const icon = createElement('span', {\n className: 'section-nav-icon',\n textContent: section.icon,\n })\n button.appendChild(icon)\n }\n\n // ラベル\n const label = createElement('span', {\n className: 'section-nav-label',\n textContent: section.label,\n })\n button.appendChild(label)\n\n // クリックイベント\n if (!section.disabled) {\n button.addEventListener('click', () => this.scrollToSection(section.id))\n }\n\n li.appendChild(button)\n return li\n }\n\n /**\n * モバイル用ドロップダウンをレンダリング\n */\n private renderMobileDropdown(): HTMLElement {\n const dropdown = createElement('div', {\n className: 'section-nav-dropdown',\n })\n\n const activeSection = this.getActiveSection()\n\n const trigger = createElement('button', {\n className: 'section-nav-dropdown-trigger',\n attributes: {\n type: 'button',\n 'aria-haspopup': 'listbox',\n 'aria-expanded': 'false',\n },\n })\n\n // アイコン(XSS防止のためtextContentを使用)\n if (activeSection?.icon) {\n const icon = createElement('span', {\n className: 'section-nav-icon',\n textContent: activeSection.icon,\n })\n trigger.appendChild(icon)\n }\n\n const label = createElement('span', {\n className: 'section-nav-label',\n textContent: activeSection?.label ?? 'セクション選択',\n })\n trigger.appendChild(label)\n\n const chevron = createElement('span', {\n className: 'section-nav-chevron',\n textContent: '▼',\n })\n trigger.appendChild(chevron)\n\n // ドロップダウンメニュー\n const menu = createElement('ul', {\n className: 'section-nav-dropdown-menu',\n attributes: { role: 'listbox', hidden: 'true' },\n })\n\n for (const section of this.state.sections) {\n const isActive = section.id === this.state.activeSectionId\n const option = createElement('li', {\n className: `section-nav-dropdown-item ${isActive ? 'active' : ''} ${section.disabled ? 'disabled' : ''}`,\n attributes: {\n role: 'option',\n 'aria-selected': String(isActive),\n },\n })\n\n // アイコン(XSS防止のためtextContentを使用)\n if (section.icon) {\n const icon = createElement('span', {\n className: 'section-nav-icon',\n textContent: section.icon,\n })\n option.appendChild(icon)\n }\n\n const optionLabel = createElement('span', {\n className: 'section-nav-label',\n textContent: section.label,\n })\n option.appendChild(optionLabel)\n\n if (!section.disabled) {\n option.addEventListener('click', () => {\n this.scrollToSection(section.id)\n menu.setAttribute('hidden', 'true')\n trigger.setAttribute('aria-expanded', 'false')\n })\n }\n\n menu.appendChild(option)\n }\n\n // トリガークリックでドロップダウン開閉\n trigger.addEventListener('click', () => {\n const isExpanded = trigger.getAttribute('aria-expanded') === 'true'\n trigger.setAttribute('aria-expanded', String(!isExpanded))\n if (isExpanded) {\n menu.setAttribute('hidden', 'true')\n } else {\n menu.removeAttribute('hidden')\n }\n })\n\n // 外側クリックで閉じる(イベントリスナーを保持してクリーンアップ可能に)\n this.documentClickHandler = (e: MouseEvent) => {\n if (!dropdown.contains(e.target as Node)) {\n menu.setAttribute('hidden', 'true')\n trigger.setAttribute('aria-expanded', 'false')\n }\n }\n document.addEventListener('click', this.documentClickHandler)\n\n dropdown.appendChild(trigger)\n dropdown.appendChild(menu)\n return dropdown\n }\n\n /**\n * Intersection Observerをセットアップ\n */\n private setupIntersectionObserver(): void {\n if (this.observer) {\n this.observer.disconnect()\n }\n\n const rootMargin = this.config.rootMargin ?? DEFAULT_ROOT_MARGIN\n const threshold = this.config.threshold ?? 0\n\n this.observer = new IntersectionObserver(\n (entries) => this.handleIntersection(entries),\n { rootMargin, threshold }\n )\n\n // 各セクション要素を監視\n for (const section of this.state.sections) {\n const element = document.getElementById(section.id)\n if (element) {\n this.observer.observe(element)\n }\n }\n }\n\n /**\n * Intersection Observerのコールバック\n */\n private handleIntersection(entries: IntersectionObserverEntry[]): void {\n // スクロール中は無視\n if (this.isScrolling) {\n return\n }\n\n for (const entry of entries) {\n if (entry.isIntersecting) {\n const sectionId = entry.target.id\n const section = this.state.sections.find(s => s.id === sectionId)\n\n if (section && !section.disabled && sectionId !== this.state.activeSectionId) {\n this.state = {\n ...this.state,\n activeSectionId: sectionId,\n }\n\n this.updateActiveStyles()\n this.callbacks.onActiveChange?.(sectionId, this.getState())\n }\n }\n }\n }\n\n /**\n * アクティブスタイルを更新\n */\n private updateActiveStyles(): void {\n const items = this.container.querySelectorAll('.section-nav-item')\n items.forEach(item => {\n const button = item.querySelector('.section-nav-button')\n const sectionId = button?.getAttribute('data-section-id')\n\n if (sectionId === this.state.activeSectionId) {\n item.classList.add('active')\n button?.setAttribute('aria-current', 'location')\n } else {\n item.classList.remove('active')\n button?.removeAttribute('aria-current')\n }\n })\n\n // モバイルドロップダウンも更新\n const dropdownTrigger = this.container.querySelector('.section-nav-dropdown-trigger')\n if (dropdownTrigger) {\n const activeSection = this.getActiveSection()\n const labelEl = dropdownTrigger.querySelector('.section-nav-label')\n const iconEl = dropdownTrigger.querySelector('.section-nav-icon')\n\n if (labelEl) {\n labelEl.textContent = activeSection?.label ?? 'セクション選択'\n }\n if (iconEl && activeSection?.icon) {\n iconEl.textContent = activeSection.icon\n }\n }\n\n // ドロップダウンメニュー内のアクティブ状態も更新\n const dropdownItems = this.container.querySelectorAll('.section-nav-dropdown-item')\n dropdownItems.forEach((item, index) => {\n const section = this.state.sections[index]\n if (section?.id === this.state.activeSectionId) {\n item.classList.add('active')\n item.setAttribute('aria-selected', 'true')\n } else {\n item.classList.remove('active')\n item.setAttribute('aria-selected', 'false')\n }\n })\n }\n\n // ===========================================================================\n // Static Field Renderer\n // ===========================================================================\n\n static renderField(field: InputField): string {\n const sectionNavHtml = `\n <nav class=\"mokkun-section-nav\" aria-label=\"${escapeHtml(field.label)}\">\n <ul class=\"section-nav-list\">\n <li class=\"section-nav-item active\">\n <a href=\"#section1\" class=\"section-nav-link\">セクション1</a>\n </li>\n <li class=\"section-nav-item\">\n <a href=\"#section2\" class=\"section-nav-link\">セクション2</a>\n </li>\n <li class=\"section-nav-item\">\n <a href=\"#section3\" class=\"section-nav-link\">セクション3</a>\n </li>\n </ul>\n </nav>\n `\n return createFieldWrapper(field, sectionNavHtml)\n }\n}\n","/**\n * DefinitionList Component\n * 定義リストコンポーネント\n *\n * \n * - 水平/垂直レイアウト\n * - ラベル幅調整\n * - グループ化\n * - レスポンシブ対応\n * - maxColumns設定\n * - セマンティックHTML(dl/dt/dd)\n */\n\nimport { createElement } from '../utils/dom'\nimport { escapeHtml, createFieldWrapper } from '../utils/field-helpers'\nimport type { InputField } from '../../types/schema'\n\n// =============================================================================\n// Types\n// =============================================================================\n\n/**\n * 定義リストのアイテム\n */\nexport interface DefinitionListItem {\n /** 用語(ラベル/キー) */\n term: string\n /** 説明(値) */\n description: string | string[] | null\n /** アイテム固有の全幅表示 */\n fullWidth?: boolean\n /** アイテム固有のカラム数 */\n maxColumns?: number\n /** カスタムクラス */\n className?: string\n}\n\n/**\n * 定義リストのグループ\n */\nexport interface DefinitionListGroup {\n /** グループタイトル */\n title: string\n /** グループ内のアイテム */\n items: DefinitionListItem[]\n /** グループ固有のレイアウト */\n layout?: 'horizontal' | 'vertical'\n /** グループ固有のカラム数 */\n maxColumns?: number\n}\n\n/**\n * 定義リストの状態\n */\nexport interface DefinitionListState {\n /** 現在のアイテム */\n items: DefinitionListItem[]\n /** 現在のグループ(グループ化時) */\n groups: DefinitionListGroup[]\n /** グループ化モード */\n isGrouped: boolean\n}\n\n/**\n * 定義リストのコールバック\n */\nexport interface DefinitionListCallbacks {\n /** アイテムクリック時 */\n onItemClick?: (item: DefinitionListItem, index: number) => void\n /** グループクリック時 */\n onGroupClick?: (group: DefinitionListGroup, index: number) => void\n}\n\n/**\n * 用語のスタイルタイプ\n */\nexport type TermStyleType = 'blockTitle' | 'subBlockTitle' | 'subSubBlockTitle'\n\n/**\n * 定義リストの設定\n */\nexport interface DefinitionListConfig {\n /** アイテム配列(フラットリスト用) */\n items?: DefinitionListItem[]\n /** グループ配列(グループ化リスト用) */\n groups?: DefinitionListGroup[]\n /** レイアウト方向(デフォルト: horizontal) */\n layout?: 'horizontal' | 'vertical'\n /** 最大カラム数(デフォルト: 自動) */\n maxColumns?: 1 | 2 | 3 | 4\n /** 用語(ラベル)の幅 */\n termWidth?: string | number\n /** 用語のスタイルタイプ */\n termStyleType?: TermStyleType\n /** アイテム間のギャップ */\n gap?: string | number\n /** ボーダーを表示 */\n bordered?: boolean\n /** ストライプ表示 */\n striped?: boolean\n /** コンパクト表示 */\n compact?: boolean\n /** クリック可能 */\n clickable?: boolean\n /** 空の値の表示テキスト */\n emptyText?: string\n}\n\n// =============================================================================\n// DefinitionList Class\n// =============================================================================\n\n/**\n * 定義リストコンポーネント\n */\nexport class DefinitionList {\n private config: DefinitionListConfig\n private state: DefinitionListState\n private callbacks: DefinitionListCallbacks\n private container: HTMLElement\n\n constructor(\n container: HTMLElement,\n config: DefinitionListConfig = {},\n callbacks: DefinitionListCallbacks = {}\n ) {\n this.config = config\n this.container = container\n this.callbacks = callbacks\n this.state = this.createInitialState()\n }\n\n // ===========================================================================\n // Public Methods\n // ===========================================================================\n\n /**\n * 定義リストをレンダリング\n */\n render(): void {\n this.container.innerHTML = ''\n\n const layout = this.config.layout ?? 'horizontal'\n const maxColumns = this.config.maxColumns\n const bordered = this.config.bordered ?? false\n const striped = this.config.striped ?? false\n const compact = this.config.compact ?? false\n\n // メインコンテナの設定\n this.container.className = 'mokkun-definition-list'\n this.container.setAttribute('data-layout', layout)\n\n if (maxColumns) {\n this.container.setAttribute('data-columns', String(maxColumns))\n }\n\n if (bordered) {\n this.container.classList.add('definition-list-bordered')\n }\n\n if (striped) {\n this.container.classList.add('definition-list-striped')\n }\n\n if (compact) {\n this.container.classList.add('definition-list-compact')\n }\n\n // CSS変数の設定\n this.applyCustomStyles()\n\n // グループ化モードかフラットリストかで分岐\n if (this.state.isGrouped && this.state.groups.length > 0) {\n this.renderGroups()\n } else {\n this.renderItems(this.state.items)\n }\n }\n\n /**\n * アイテムを設定\n */\n setItems(items: DefinitionListItem[]): void {\n this.state = {\n ...this.state,\n items,\n groups: [],\n isGrouped: false,\n }\n this.render()\n }\n\n /**\n * グループを設定\n */\n setGroups(groups: DefinitionListGroup[]): void {\n this.state = {\n ...this.state,\n items: [],\n groups,\n isGrouped: true,\n }\n this.render()\n }\n\n /**\n * アイテムを追加\n */\n addItem(item: DefinitionListItem): void {\n this.state = {\n ...this.state,\n items: [...this.state.items, item],\n }\n this.render()\n }\n\n /**\n * アイテムを削除\n */\n removeItem(index: number): void {\n if (index < 0 || index >= this.state.items.length) {\n return\n }\n\n this.state = {\n ...this.state,\n items: this.state.items.filter((_, i) => i !== index),\n }\n this.render()\n }\n\n /**\n * アイテムを更新\n */\n updateItem(index: number, item: Partial<DefinitionListItem>): void {\n if (index < 0 || index >= this.state.items.length) {\n return\n }\n\n this.state = {\n ...this.state,\n items: this.state.items.map((existingItem, i) =>\n i === index ? { ...existingItem, ...item } : existingItem\n ),\n }\n this.render()\n }\n\n /**\n * 現在の状態を取得\n */\n getState(): Readonly<DefinitionListState> {\n return { ...this.state }\n }\n\n /**\n * コンポーネントを破棄\n */\n destroy(): void {\n this.container.innerHTML = ''\n }\n\n // ===========================================================================\n // Private Methods\n // ===========================================================================\n\n /**\n * 初期状態を作成\n */\n private createInitialState(): DefinitionListState {\n const items = this.config.items ?? []\n const groups = this.config.groups ?? []\n const isGrouped = groups.length > 0\n\n return {\n items: isGrouped ? [] : items,\n groups,\n isGrouped,\n }\n }\n\n /**\n * カスタムスタイルを適用\n */\n private applyCustomStyles(): void {\n // 用語の幅\n if (this.config.termWidth) {\n const width =\n typeof this.config.termWidth === 'number'\n ? `${this.config.termWidth}px`\n : this.config.termWidth\n this.container.style.setProperty('--definition-term-width', width)\n }\n\n // ギャップ\n if (this.config.gap) {\n const gap =\n typeof this.config.gap === 'number'\n ? `${this.config.gap}px`\n : this.config.gap\n this.container.style.setProperty('--definition-gap', gap)\n }\n }\n\n /**\n * グループをレンダリング\n */\n private renderGroups(): void {\n this.state.groups.forEach((group, groupIndex) => {\n const groupElement = this.renderGroup(group, groupIndex)\n this.container.appendChild(groupElement)\n })\n }\n\n /**\n * 単一のグループをレンダリング\n */\n private renderGroup(group: DefinitionListGroup, groupIndex: number): HTMLElement {\n const groupContainer = createElement('div', {\n className: 'definition-group',\n attributes: {\n 'data-group-index': String(groupIndex),\n },\n })\n\n // グループタイトル\n const titleElement = createElement('div', {\n className: 'definition-group-title',\n textContent: group.title,\n })\n groupContainer.appendChild(titleElement)\n\n // グループ内のアイテム\n const listContainer = createElement('dl', {\n className: 'definition-list-content',\n attributes: {\n 'aria-label': group.title,\n },\n })\n\n // グループ固有のレイアウト設定\n if (group.layout) {\n listContainer.setAttribute('data-layout', group.layout)\n }\n\n if (group.maxColumns) {\n listContainer.setAttribute('data-columns', String(group.maxColumns))\n }\n\n // グループクリックイベント\n if (this.callbacks.onGroupClick) {\n groupContainer.style.cursor = 'pointer'\n groupContainer.addEventListener('click', (e) => {\n // アイテムクリック時は伝播しない\n if ((e.target as HTMLElement).closest('.definition-item')) {\n return\n }\n this.callbacks.onGroupClick?.(group, groupIndex)\n })\n }\n\n group.items.forEach((item, itemIndex) => {\n const itemElements = this.renderItem(item, itemIndex)\n itemElements.forEach((el) => listContainer.appendChild(el))\n })\n\n groupContainer.appendChild(listContainer)\n return groupContainer\n }\n\n /**\n * アイテムリストをレンダリング\n */\n private renderItems(items: DefinitionListItem[]): void {\n const listContainer = createElement('dl', {\n className: 'definition-list-content',\n attributes: {\n 'aria-label': 'Definition list',\n },\n })\n\n items.forEach((item, index) => {\n const itemElements = this.renderItem(item, index)\n itemElements.forEach((el) => listContainer.appendChild(el))\n })\n\n this.container.appendChild(listContainer)\n }\n\n /**\n * 単一のアイテムをレンダリング(dt + dd のペア)\n */\n private renderItem(item: DefinitionListItem, index: number): HTMLElement[] {\n const elements: HTMLElement[] = []\n const clickable = this.config.clickable ?? false\n const emptyText = this.config.emptyText ?? '-'\n const termStyleType = this.config.termStyleType\n\n // classNameのサニタイズ(安全な文字のみ許可)\n const sanitizedClassName = item.className\n ? item.className.replace(/[^a-zA-Z0-9_\\-\\s]/g, '')\n : ''\n\n // アイテムラッパー(グリッド配置用)\n const itemWrapper = createElement('div', {\n className: `definition-item${sanitizedClassName ? ` ${sanitizedClassName}` : ''}`,\n attributes: {\n 'data-index': String(index),\n },\n })\n\n // 全幅表示\n if (item.fullWidth) {\n itemWrapper.setAttribute('data-full-width', '')\n }\n\n // アイテム固有のカラム数\n if (item.maxColumns) {\n itemWrapper.setAttribute('data-columns', String(item.maxColumns))\n }\n\n // 用語(dt)\n const termElement = createElement('dt', {\n className: `definition-term${termStyleType ? ` term-${termStyleType}` : ''}`,\n textContent: item.term,\n })\n\n // 説明(dd)\n const descriptionElement = createElement('dd', {\n className: 'definition-description',\n })\n\n // 説明の内容を設定\n if (item.description === null || item.description === undefined) {\n descriptionElement.textContent = emptyText\n descriptionElement.classList.add('definition-description-empty')\n } else if (Array.isArray(item.description)) {\n if (item.description.length === 0) {\n descriptionElement.textContent = emptyText\n descriptionElement.classList.add('definition-description-empty')\n } else {\n // 複数の値をリストとして表示\n const list = createElement('ul', {\n className: 'definition-description-list',\n })\n item.description.forEach((desc) => {\n const listItem = createElement('li', { textContent: desc })\n list.appendChild(listItem)\n })\n descriptionElement.appendChild(list)\n }\n } else {\n descriptionElement.textContent = item.description\n }\n\n // クリックイベント\n if (clickable && this.callbacks.onItemClick) {\n itemWrapper.style.cursor = 'pointer'\n itemWrapper.setAttribute('role', 'button')\n itemWrapper.setAttribute('tabindex', '0')\n\n itemWrapper.addEventListener('click', () => {\n this.callbacks.onItemClick?.(item, index)\n })\n\n itemWrapper.addEventListener('keydown', (e) => {\n if (e.key === 'Enter' || e.key === ' ') {\n e.preventDefault()\n this.callbacks.onItemClick?.(item, index)\n }\n })\n }\n\n itemWrapper.appendChild(termElement)\n itemWrapper.appendChild(descriptionElement)\n elements.push(itemWrapper)\n\n return elements\n }\n\n // ===========================================================================\n // Static Field Renderer\n // ===========================================================================\n\n static renderField(field: InputField): string {\n const label = escapeHtml(field.label)\n const definitionHtml = `\n <dl class=\"mokkun-definition-list\" aria-label=\"${label}\">\n <div class=\"definition-item\">\n <dt class=\"definition-term\">項目1</dt>\n <dd class=\"definition-description\">値1</dd>\n </div>\n <div class=\"definition-item\">\n <dt class=\"definition-term\">項目2</dt>\n <dd class=\"definition-description\">値2</dd>\n </div>\n <div class=\"definition-item\">\n <dt class=\"definition-term\">項目3</dt>\n <dd class=\"definition-description\">値3</dd>\n </div>\n </dl>\n `\n return createFieldWrapper(field, definitionHtml)\n }\n}\n\n// =============================================================================\n// Factory Function\n// =============================================================================\n\n/**\n * 定義リストを作成\n */\nexport function createDefinitionList(\n container: HTMLElement,\n config: DefinitionListConfig = {},\n callbacks: DefinitionListCallbacks = {}\n): DefinitionList {\n const definitionList = new DefinitionList(container, config, callbacks)\n definitionList.render()\n return definitionList\n}\n","/**\n * Stepper Component\n * \n *\n * 連続する操作をステップごとにグルーピングするコンポーネント\n * ステップの進行状況に応じて現在地や完了のステータスを表現\n */\n\nimport { createElement, clearElement } from '../utils/dom'\nimport { createFieldWrapper } from '../utils/field-helpers'\nimport type { InputField } from '../../types/schema'\n\n// =============================================================================\n// Types\n// =============================================================================\n\n/**\n * ステップのステータス\n * - completed: 完了(チェックアイコン)\n * - closed: 中断(×アイコン)\n */\nexport type StepperStatus = 'completed' | 'closed'\n\n/**\n * 拡張ステータス(カスタムテキスト付き)\n */\nexport interface StepperStatusWithText {\n type: StepperStatus\n text: string\n}\n\n/**\n * 基本ステップ定義\n */\nexport interface Step {\n /** ステップのラベル */\n label: string\n /** ステータス(オプション) */\n status?: StepperStatus | StepperStatusWithText\n}\n\n/**\n * 水平ステップ(HorizontalStepper用)\n */\nexport type HorizontalStep = Step\n\n/**\n * 垂直ステップ(VerticalStepper用)- 子要素を持てる\n */\nexport interface VerticalStep extends Step {\n /** 子要素のHTML */\n children?: string\n}\n\n/**\n * Stepperの設定\n */\nexport interface StepperConfig {\n /** レイアウトタイプ */\n type: 'horizontal' | 'vertical'\n /** ステップ配列 */\n steps: HorizontalStep[] | VerticalStep[]\n /** 現在のステップインデックス(0始まり) */\n activeIndex?: number\n}\n\n/**\n * Stepperの状態\n */\nexport interface StepperState {\n /** 現在のステップインデックス */\n activeIndex: number\n /** レイアウトタイプ */\n type: 'horizontal' | 'vertical'\n}\n\n/**\n * Stepperのコールバック\n */\nexport interface StepperCallbacks {\n /** ステップクリック時(過去のステップのみ) */\n onStepClick?: (index: number) => void\n}\n\n// =============================================================================\n// Helper Functions\n// =============================================================================\n\n/**\n * ステータスタイプを取得\n */\nfunction getStatusType(status: StepperStatus | StepperStatusWithText | undefined): StepperStatus | undefined {\n if (!status) return undefined\n if (typeof status === 'string') return status\n return status.type\n}\n\n/**\n * ステータスのaltテキストを取得\n */\nfunction getStatusAltText(status: StepperStatus | StepperStatusWithText | undefined): string {\n if (!status) return ''\n if (typeof status === 'string') {\n return status === 'completed' ? '完了' : '中断'\n }\n return status.text || (status.type === 'completed' ? '完了' : '中断')\n}\n\n/**\n * チェックアイコンSVGを作成\n */\nfunction createCheckIcon(): SVGSVGElement {\n const svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg')\n svg.setAttribute('viewBox', '0 0 512 512')\n svg.setAttribute('width', '1em')\n svg.setAttribute('height', '1em')\n svg.setAttribute('fill', 'currentColor')\n svg.setAttribute('aria-hidden', 'true')\n svg.classList.add('stepper-icon', 'stepper-icon-check')\n\n const path = document.createElementNS('http://www.w3.org/2000/svg', 'path')\n path.setAttribute('d', 'M256 512A256 256 0 1 0 256 0a256 256 0 1 0 0 512zM369 209L241 337c-9.4 9.4-24.6 9.4-33.9 0l-64-64c-9.4-9.4-9.4-24.6 0-33.9s24.6-9.4 33.9 0l47 47L335 175c9.4-9.4 24.6-9.4 33.9 0s9.4 24.6 0 33.9z')\n svg.appendChild(path)\n\n return svg\n}\n\n/**\n * ×アイコンSVGを作成\n */\nfunction createCloseIcon(): SVGSVGElement {\n const svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg')\n svg.setAttribute('viewBox', '0 0 512 512')\n svg.setAttribute('width', '1em')\n svg.setAttribute('height', '1em')\n svg.setAttribute('fill', 'currentColor')\n svg.setAttribute('aria-hidden', 'true')\n svg.classList.add('stepper-icon', 'stepper-icon-close')\n\n const path = document.createElementNS('http://www.w3.org/2000/svg', 'path')\n path.setAttribute('d', 'M256 512A256 256 0 1 0 256 0a256 256 0 1 0 0 512zM175 175c9.4-9.4 24.6-9.4 33.9 0l47 47 47-47c9.4-9.4 24.6-9.4 33.9 0s9.4 24.6 0 33.9l-47 47 47 47c9.4 9.4 9.4 24.6 0 33.9s-24.6 9.4-33.9 0l-47-47-47 47c-9.4 9.4-24.6 9.4-33.9 0s-9.4-24.6 0-33.9l47-47-47-47c-9.4-9.4-9.4-24.6 0-33.9z')\n svg.appendChild(path)\n\n return svg\n}\n\n// =============================================================================\n// Stepper Component\n// =============================================================================\n\n/**\n * Stepperコンポーネント\n * \n */\nexport class Stepper {\n private config: StepperConfig\n private container: HTMLElement\n private state: StepperState\n\n constructor(\n config: StepperConfig,\n container: HTMLElement,\n _callbacks: StepperCallbacks = {}\n ) {\n this.config = config\n this.container = container\n // callbacks will be used for future event handling\n void _callbacks\n this.state = this.createInitialState()\n }\n\n /**\n * 初期状態を作成\n */\n private createInitialState(): StepperState {\n return {\n activeIndex: this.config.activeIndex ?? 0,\n type: this.config.type,\n }\n }\n\n /**\n * 状態を取得\n */\n getState(): StepperState {\n return { ...this.state }\n }\n\n /**\n * 現在のステップを設定\n */\n setActiveIndex(index: number): void {\n if (index >= 0 && index < this.config.steps.length) {\n this.state = {\n ...this.state,\n activeIndex: index,\n }\n this.render()\n }\n }\n\n /**\n * レンダリング\n */\n render(): void {\n clearElement(this.container)\n this.container.className = `mokkun-stepper stepper-${this.state.type}`\n\n if (this.state.type === 'horizontal') {\n this.renderHorizontal()\n } else {\n this.renderVertical()\n }\n }\n\n /**\n * 水平レイアウトをレンダリング\n */\n private renderHorizontal(): void {\n const ol = createElement('ol', {\n className: 'stepper-list stepper-list-horizontal',\n })\n ol.setAttribute('role', 'list')\n\n const steps = this.config.steps as HorizontalStep[]\n steps.forEach((step, index) => {\n const li = this.renderHorizontalStep(step, index)\n ol.appendChild(li)\n })\n\n this.container.appendChild(ol)\n }\n\n /**\n * 水平ステップアイテムをレンダリング\n */\n private renderHorizontalStep(step: HorizontalStep, index: number): HTMLElement {\n const isCurrent = index === this.state.activeIndex\n const isPast = index < this.state.activeIndex\n const statusType = getStatusType(step.status)\n const isCompleted = statusType === 'completed' || (isPast && !statusType)\n const isClosed = statusType === 'closed'\n const isPrevCompleted = index > 0 && (\n getStatusType(this.config.steps[index - 1].status) === 'completed' ||\n (index - 1 < this.state.activeIndex)\n )\n\n const li = createElement('li', {\n className: [\n 'stepper-item',\n 'stepper-item-horizontal',\n isCurrent ? 'is-current' : '',\n isCompleted ? 'is-completed' : '',\n isClosed ? 'is-closed' : '',\n ].filter(Boolean).join(' '),\n })\n\n if (isCurrent) {\n li.setAttribute('aria-current', 'step')\n }\n\n // ラベルラッパー\n const labelWrapper = createElement('div', { className: 'stepper-label-wrapper' })\n\n // カウンターラッパー(線 + カウンター + 線)\n const counterWrapper = createElement('div', { className: 'stepper-counter-wrapper' })\n\n // 前の線\n const beforeLine = createElement('span', {\n className: [\n 'stepper-line',\n 'stepper-line-before',\n isPrevCompleted ? 'is-completed' : '',\n index === 0 ? 'is-hidden' : '',\n ].filter(Boolean).join(' '),\n })\n counterWrapper.appendChild(beforeLine)\n\n // ステップカウンター\n const counter = this.renderStepCounter(index, isCurrent, step.status)\n counterWrapper.appendChild(counter)\n\n // 後の線\n const afterLine = createElement('span', {\n className: [\n 'stepper-line',\n 'stepper-line-after',\n isCompleted ? 'is-completed' : '',\n index === this.config.steps.length - 1 ? 'is-hidden' : '',\n ].filter(Boolean).join(' '),\n })\n counterWrapper.appendChild(afterLine)\n\n labelWrapper.appendChild(counterWrapper)\n\n // ラベル\n const label = createElement('span', {\n className: [\n 'stepper-label',\n isCurrent ? 'is-current' : '',\n isClosed ? 'is-closed' : '',\n ].filter(Boolean).join(' '),\n textContent: step.label,\n })\n labelWrapper.appendChild(label)\n\n li.appendChild(labelWrapper)\n\n return li\n }\n\n /**\n * 垂直レイアウトをレンダリング\n */\n private renderVertical(): void {\n const ol = createElement('ol', {\n className: 'stepper-list stepper-list-vertical',\n })\n ol.setAttribute('role', 'list')\n\n const steps = this.config.steps as VerticalStep[]\n steps.forEach((step, index) => {\n const li = this.renderVerticalStep(step, index)\n ol.appendChild(li)\n })\n\n this.container.appendChild(ol)\n }\n\n /**\n * 垂直ステップアイテムをレンダリング\n */\n private renderVerticalStep(step: VerticalStep, index: number): HTMLElement {\n const isCurrent = index === this.state.activeIndex\n const isPast = index < this.state.activeIndex\n const statusType = getStatusType(step.status)\n const isCompleted = statusType === 'completed' || (isPast && !statusType)\n const isClosed = statusType === 'closed'\n const isLast = index === this.config.steps.length - 1\n\n const li = createElement('li', {\n className: [\n 'stepper-item',\n 'stepper-item-vertical',\n isCurrent ? 'is-current' : '',\n isCompleted ? 'is-completed' : '',\n isClosed ? 'is-closed' : '',\n isLast ? 'is-last' : '',\n ].filter(Boolean).join(' '),\n })\n\n if (isCurrent) {\n li.setAttribute('aria-current', 'step')\n }\n\n // セクション\n const section = createElement('div', { className: 'stepper-section' })\n\n // カウンター(縦線はCSSのafter疑似要素で実装)\n const counterArea = createElement('div', { className: 'stepper-counter-area' })\n const counter = this.renderStepCounter(index, isCurrent, step.status)\n counterArea.appendChild(counter)\n section.appendChild(counterArea)\n\n // ボディ\n const body = createElement('div', { className: 'stepper-body' })\n\n // ヘッダー(ラベル)\n const heading = createElement('div', {\n className: [\n 'stepper-heading',\n isCurrent ? 'is-current' : '',\n (isCompleted || isClosed) && !isCurrent ? 'is-inactive' : '',\n ].filter(Boolean).join(' '),\n textContent: step.label,\n })\n body.appendChild(heading)\n\n // 子要素\n if (step.children) {\n const inner = createElement('div', { className: 'stepper-inner' })\n inner.innerHTML = step.children\n body.appendChild(inner)\n }\n\n section.appendChild(body)\n li.appendChild(section)\n\n return li\n }\n\n /**\n * ステップカウンターをレンダリング\n */\n private renderStepCounter(\n index: number,\n isCurrent: boolean,\n status?: StepperStatus | StepperStatusWithText\n ): HTMLElement {\n const statusType = getStatusType(status)\n const hasStatus = statusType === 'completed' || statusType === 'closed'\n\n const counter = createElement('span', {\n className: [\n 'stepper-counter',\n isCurrent ? 'is-current' : '',\n statusType === 'completed' ? 'is-completed' : '',\n statusType === 'closed' ? 'is-closed' : '',\n ].filter(Boolean).join(' '),\n })\n\n // 番号\n const number = createElement('span', {\n className: 'stepper-number',\n textContent: String(index + 1),\n })\n number.setAttribute('aria-hidden', 'true')\n counter.appendChild(number)\n\n // ステータスアイコン\n if (hasStatus) {\n const iconWrapper = createElement('span', {\n className: 'stepper-status-icon',\n })\n iconWrapper.setAttribute('role', 'img')\n iconWrapper.setAttribute('aria-label', getStatusAltText(status))\n\n if (statusType === 'completed') {\n iconWrapper.appendChild(createCheckIcon())\n } else if (statusType === 'closed') {\n iconWrapper.appendChild(createCloseIcon())\n }\n\n counter.appendChild(iconWrapper)\n }\n\n return counter\n }\n\n /**\n * クリーンアップ\n */\n destroy(): void {\n clearElement(this.container)\n }\n\n // ===========================================================================\n // Static Field Renderer\n // ===========================================================================\n\n static renderField(field: InputField): string {\n const stepperHtml = `\n <div class=\"mokkun-stepper\">\n <div class=\"stepper-step completed\">\n <div class=\"step-indicator\">1</div>\n <div class=\"step-label\">ステップ1</div>\n </div>\n <div class=\"stepper-connector\"></div>\n <div class=\"stepper-step active\">\n <div class=\"step-indicator\">2</div>\n <div class=\"step-label\">ステップ2</div>\n </div>\n <div class=\"stepper-connector\"></div>\n <div class=\"stepper-step\">\n <div class=\"step-indicator\">3</div>\n <div class=\"step-label\">ステップ3</div>\n </div>\n </div>\n `\n return createFieldWrapper(field, stepperHtml)\n }\n}\n\n/**\n * Stepperを作成するファクトリ関数\n */\nexport function createStepper(\n config: StepperConfig,\n container: HTMLElement,\n callbacks: StepperCallbacks = {}\n): Stepper {\n const stepper = new Stepper(config, container, callbacks)\n stepper.render()\n return stepper\n}\n","/**\n * InformationPanel Component\n * 情報パネルコンポーネント\n *\n * \n * - タイプ(info/success/warning/error/sync)\n * - アイコン表示\n * - 開閉ボタン(toggleable)\n * - タイトル付き(必須)\n * - 太字表示(bold)\n * - アクセシビリティ対応(ARIA属性)\n *\n * @see https://smarthr.design/products/components/information-panel/\n */\n\nimport { createElement, generateId } from '../utils/dom'\nimport { escapeHtml, createFieldWrapper } from '../utils/field-helpers'\nimport type { InputField } from '../../types/schema'\n\n// =============================================================================\n// Types\n// =============================================================================\n\n/**\n * 情報パネルのタイプ\n * - info: 一般情報(青)\n * - success: 成功・完了(緑)\n * - warning: 警告・注意(黄)\n * - error: エラー(赤)\n * - sync: 同期中(灰色)\n */\nexport type InformationPanelType = 'info' | 'success' | 'warning' | 'error' | 'sync'\n\n/**\n * 情報パネルの状態\n */\nexport interface InformationPanelState {\n /** パネルが展開されているか(toggleableの場合) */\n active: boolean\n /** 非表示状態 */\n hidden: boolean\n}\n\n/**\n * 情報パネルのコールバック\n */\nexport interface InformationPanelCallbacks {\n /** 開閉ボタンクリック時 */\n onClickTrigger?: (active: boolean) => void\n /** 閉じるボタンクリック時(非toggleable時) */\n onClose?: () => void\n}\n\n/**\n * 情報パネルの設定\n */\nexport interface InformationPanelConfig {\n /** パネルのタイトル(必須) */\n title: string\n /** パネルの内容(HTML文字列またはHTMLElement) */\n content: string | HTMLElement\n /** タイプ(デフォルト: info) */\n type?: InformationPanelType\n /** 開閉ボタンを表示するか(デフォルト: false) */\n toggleable?: boolean\n /** 初期展開状態(toggleableの場合、デフォルト: true) */\n defaultActive?: boolean\n /** タイトルを太字にするか(デフォルト: false) */\n bold?: boolean\n /** 閉じるボタンを表示するか(デフォルト: false) */\n closable?: boolean\n /** ID属性 */\n id?: string\n /** カスタムCSSクラス */\n className?: string\n}\n\n// =============================================================================\n// Built-in Icons\n// =============================================================================\n\nconst BUILTIN_ICONS: Record<InformationPanelType, string> = {\n info: `<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 16 16\" fill=\"currentColor\" aria-hidden=\"true\"><path fill-rule=\"evenodd\" d=\"M15 8A7 7 0 1 1 1 8a7 7 0 0 1 14 0ZM9 5a1 1 0 1 1-2 0 1 1 0 0 1 2 0ZM6.75 8a.75.75 0 0 0 0 1.5h.75v1.75a.75.75 0 0 0 1.5 0v-2.5A.75.75 0 0 0 8.25 8h-1.5Z\" clip-rule=\"evenodd\" /></svg>`,\n success: `<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 16 16\" fill=\"currentColor\" aria-hidden=\"true\"><path fill-rule=\"evenodd\" d=\"M8 15A7 7 0 1 0 8 1a7 7 0 0 0 0 14Zm3.844-8.791a.75.75 0 0 0-1.188-.918l-3.7 4.79-1.649-1.833a.75.75 0 1 0-1.114 1.004l2.25 2.5a.75.75 0 0 0 1.151-.043l4.25-5.5Z\" clip-rule=\"evenodd\" /></svg>`,\n warning: `<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 16 16\" fill=\"currentColor\" aria-hidden=\"true\"><path fill-rule=\"evenodd\" d=\"M6.701 2.25c.577-1 2.02-1 2.598 0l5.196 9a1.5 1.5 0 0 1-1.299 2.25H2.804a1.5 1.5 0 0 1-1.3-2.25l5.197-9ZM8 4a.75.75 0 0 1 .75.75v3a.75.75 0 0 1-1.5 0v-3A.75.75 0 0 1 8 4Zm0 8a1 1 0 1 0 0-2 1 1 0 0 0 0 2Z\" clip-rule=\"evenodd\" /></svg>`,\n error: `<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 16 16\" fill=\"currentColor\" aria-hidden=\"true\"><path fill-rule=\"evenodd\" d=\"M8 15A7 7 0 1 0 8 1a7 7 0 0 0 0 14ZM8 4a.75.75 0 0 1 .75.75v3a.75.75 0 0 1-1.5 0v-3A.75.75 0 0 1 8 4Zm0 8a1 1 0 1 0 0-2 1 1 0 0 0 0 2Z\" clip-rule=\"evenodd\" /></svg>`,\n sync: `<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 16 16\" fill=\"currentColor\" aria-hidden=\"true\"><path fill-rule=\"evenodd\" d=\"M13.836 2.477a.75.75 0 0 1 .75.75v3.182a.75.75 0 0 1-.75.75h-3.182a.75.75 0 0 1 0-1.5h1.37l-.84-.841a4.5 4.5 0 0 0-7.08.681.75.75 0 0 1-1.264-.808 6 6 0 0 1 9.44-.908l.84.84v-1.646a.75.75 0 0 1 .75-.75Zm-1.672 9.046a.75.75 0 0 1 1.264.808 6 6 0 0 1-9.44.908l-.84-.84v1.646a.75.75 0 0 1-1.5 0V10.82a.75.75 0 0 1 .75-.75h3.182a.75.75 0 0 1 0 1.5h-1.37l.84.841a4.5 4.5 0 0 0 7.08-.681Z\" clip-rule=\"evenodd\" /></svg>`,\n}\n\n// =============================================================================\n// InformationPanel Class\n// =============================================================================\n\n/**\n * 情報パネルコンポーネント\n */\nexport class InformationPanel {\n private config: InformationPanelConfig\n private state: InformationPanelState\n private callbacks: InformationPanelCallbacks\n private container: HTMLElement\n private instanceId: string\n private contentElement: HTMLElement | null = null\n\n constructor(\n container: HTMLElement,\n config: InformationPanelConfig,\n callbacks: InformationPanelCallbacks = {}\n ) {\n this.config = config\n this.container = container\n this.callbacks = callbacks\n this.instanceId = config.id ?? generateId('information-panel')\n this.state = this.createInitialState()\n }\n\n // ===========================================================================\n // Public Methods\n // ===========================================================================\n\n /**\n * 情報パネルをレンダリング\n */\n render(): void {\n this.container.innerHTML = ''\n this.contentElement = null\n\n const type = this.config.type ?? 'info'\n const toggleable = this.config.toggleable ?? false\n const bold = this.config.bold ?? false\n\n this.container.className = [\n 'mokkun-information-panel',\n `information-panel-${type}`,\n toggleable ? 'information-panel-toggleable' : '',\n bold ? 'information-panel-bold' : '',\n this.state.active ? 'is-active' : '',\n this.config.className ?? '',\n ]\n .filter(Boolean)\n .join(' ')\n\n this.container.id = this.instanceId\n this.container.setAttribute('data-type', type)\n\n if (this.state.hidden) {\n this.container.setAttribute('data-hidden', '')\n this.container.style.display = 'none'\n return\n } else {\n this.container.removeAttribute('data-hidden')\n this.container.style.display = ''\n }\n\n // ヘッダー\n const header = this.renderHeader()\n this.container.appendChild(header)\n\n // コンテンツ\n const content = this.renderContent()\n this.container.appendChild(content)\n this.contentElement = content\n }\n\n /**\n * パネルを開く\n */\n open(): void {\n if (!(this.config.toggleable ?? false)) {\n return\n }\n\n if (this.state.active) {\n return\n }\n\n this.state = {\n ...this.state,\n active: true,\n }\n\n this.updateActiveState()\n this.callbacks.onClickTrigger?.(true)\n }\n\n /**\n * パネルを閉じる\n */\n close(): void {\n if (!(this.config.toggleable ?? false)) {\n return\n }\n\n if (!this.state.active) {\n return\n }\n\n this.state = {\n ...this.state,\n active: false,\n }\n\n this.updateActiveState()\n this.callbacks.onClickTrigger?.(false)\n }\n\n /**\n * パネルの開閉を切り替え\n */\n toggle(): void {\n if (this.state.active) {\n this.close()\n } else {\n this.open()\n }\n }\n\n /**\n * パネルが開いているか確認\n */\n isActive(): boolean {\n return this.state.active\n }\n\n /**\n * パネルを非表示にする\n */\n hide(): void {\n if (this.state.hidden) {\n return\n }\n\n this.state = {\n ...this.state,\n hidden: true,\n }\n\n this.render()\n }\n\n /**\n * パネルを表示する\n */\n show(): void {\n if (!this.state.hidden) {\n return\n }\n\n this.state = {\n ...this.state,\n hidden: false,\n }\n\n this.render()\n }\n\n /**\n * 現在の状態を取得\n */\n getState(): Readonly<InformationPanelState> {\n return { ...this.state }\n }\n\n /**\n * タイトルを更新\n */\n setTitle(title: string): void {\n this.config = {\n ...this.config,\n title,\n }\n this.render()\n }\n\n /**\n * コンテンツを更新\n */\n setContent(content: string | HTMLElement): void {\n this.config = {\n ...this.config,\n content,\n }\n this.render()\n }\n\n /**\n * タイプを更新\n */\n setType(type: InformationPanelType): void {\n this.config = {\n ...this.config,\n type,\n }\n this.render()\n }\n\n /**\n * コンポーネントを破棄\n */\n destroy(): void {\n this.container.innerHTML = ''\n this.contentElement = null\n }\n\n // ===========================================================================\n // Private Methods - Initialization\n // ===========================================================================\n\n private createInitialState(): InformationPanelState {\n const toggleable = this.config.toggleable ?? false\n const defaultActive = this.config.defaultActive ?? true\n\n return {\n active: toggleable ? defaultActive : true,\n hidden: false,\n }\n }\n\n // ===========================================================================\n // Private Methods - Rendering\n // ===========================================================================\n\n private renderHeader(): HTMLElement {\n const header = createElement('div', {\n className: 'information-panel-header',\n })\n\n // アイコン\n const icon = this.renderIcon()\n header.appendChild(icon)\n\n // タイトル\n const title = this.renderTitle()\n header.appendChild(title)\n\n // 閉じる/開閉ボタン\n const actions = this.renderActions()\n if (actions) {\n header.appendChild(actions)\n }\n\n return header\n }\n\n private renderIcon(): HTMLElement {\n const type = this.config.type ?? 'info'\n\n const iconWrapper = createElement('span', {\n className: 'information-panel-icon',\n attributes: {\n 'aria-hidden': 'true',\n },\n })\n\n iconWrapper.innerHTML = BUILTIN_ICONS[type]\n\n return iconWrapper\n }\n\n private renderTitle(): HTMLElement {\n const bold = this.config.bold ?? false\n const toggleable = this.config.toggleable ?? false\n\n const title = createElement('span', {\n className: `information-panel-title${bold ? ' is-bold' : ''}`,\n textContent: this.config.title,\n })\n\n if (toggleable) {\n title.setAttribute('id', `${this.instanceId}-title`)\n }\n\n return title\n }\n\n private renderActions(): HTMLElement | null {\n const toggleable = this.config.toggleable ?? false\n const closable = this.config.closable ?? false\n\n if (!toggleable && !closable) {\n return null\n }\n\n const actions = createElement('div', {\n className: 'information-panel-actions',\n })\n\n if (toggleable) {\n const toggleButton = this.renderToggleButton()\n actions.appendChild(toggleButton)\n } else if (closable) {\n const closeButton = this.renderCloseButton()\n actions.appendChild(closeButton)\n }\n\n return actions\n }\n\n private renderToggleButton(): HTMLElement {\n const button = createElement('button', {\n className: 'information-panel-toggle',\n attributes: {\n type: 'button',\n 'aria-expanded': String(this.state.active),\n 'aria-controls': `${this.instanceId}-content`,\n },\n })\n\n // アイコン(展開/折りたたみ)\n const icon = createElement('span', {\n className: 'information-panel-toggle-icon',\n attributes: {\n 'aria-hidden': 'true',\n },\n })\n\n // キャレットアイコン\n const svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg')\n svg.setAttribute('width', '16')\n svg.setAttribute('height', '16')\n svg.setAttribute('viewBox', '0 0 16 16')\n svg.setAttribute('fill', 'currentColor')\n\n const path = document.createElementNS('http://www.w3.org/2000/svg', 'path')\n path.setAttribute('d', 'M3 6l5 5 5-5H3z')\n\n svg.appendChild(path)\n icon.appendChild(svg)\n button.appendChild(icon)\n\n // テキスト\n const text = createElement('span', {\n className: 'information-panel-toggle-text',\n textContent: this.state.active ? '閉じる' : '開く',\n })\n button.appendChild(text)\n\n // クリックイベント\n button.addEventListener('click', () => {\n this.toggle()\n })\n\n return button\n }\n\n private renderCloseButton(): HTMLElement {\n const button = createElement('button', {\n className: 'information-panel-close',\n attributes: {\n type: 'button',\n 'aria-label': '閉じる',\n },\n })\n\n // 閉じるアイコン\n const icon = createElement('span', {\n className: 'information-panel-close-icon',\n attributes: {\n 'aria-hidden': 'true',\n },\n })\n\n const svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg')\n svg.setAttribute('width', '16')\n svg.setAttribute('height', '16')\n svg.setAttribute('viewBox', '0 0 16 16')\n svg.setAttribute('fill', 'currentColor')\n\n const path = document.createElementNS('http://www.w3.org/2000/svg', 'path')\n path.setAttribute(\n 'd',\n 'M5.28 4.22a.75.75 0 0 0-1.06 1.06L6.94 8l-2.72 2.72a.75.75 0 1 0 1.06 1.06L8 9.06l2.72 2.72a.75.75 0 1 0 1.06-1.06L9.06 8l2.72-2.72a.75.75 0 0 0-1.06-1.06L8 6.94 5.28 4.22Z'\n )\n\n svg.appendChild(path)\n icon.appendChild(svg)\n button.appendChild(icon)\n\n // クリックイベント\n button.addEventListener('click', () => {\n this.hide()\n this.callbacks.onClose?.()\n })\n\n return button\n }\n\n private renderContent(): HTMLElement {\n const toggleable = this.config.toggleable ?? false\n\n const wrapper = createElement('div', {\n className: `information-panel-content-wrapper${this.state.active ? ' is-active' : ''}`,\n })\n\n const content = createElement('div', {\n className: 'information-panel-content',\n attributes: {\n role: 'region',\n },\n })\n\n if (toggleable) {\n content.setAttribute('id', `${this.instanceId}-content`)\n content.setAttribute('aria-labelledby', `${this.instanceId}-title`)\n\n if (!this.state.active) {\n content.setAttribute('hidden', '')\n }\n }\n\n // コンテンツを追加\n if (typeof this.config.content === 'string') {\n content.innerHTML = this.config.content\n } else {\n content.appendChild(this.config.content)\n }\n\n wrapper.appendChild(content)\n\n return wrapper\n }\n\n // ===========================================================================\n // Private Methods - State Updates\n // ===========================================================================\n\n private updateActiveState(): void {\n const toggleable = this.config.toggleable ?? false\n\n if (!toggleable) {\n return\n }\n\n // コンテナの状態更新\n if (this.state.active) {\n this.container.classList.add('is-active')\n } else {\n this.container.classList.remove('is-active')\n }\n\n // トグルボタンの状態更新\n const toggleButton = this.container.querySelector('.information-panel-toggle')\n if (toggleButton) {\n toggleButton.setAttribute('aria-expanded', String(this.state.active))\n\n const icon = toggleButton.querySelector('.information-panel-toggle-icon')\n if (icon) {\n if (this.state.active) {\n icon.classList.add('is-active')\n } else {\n icon.classList.remove('is-active')\n }\n }\n\n const text = toggleButton.querySelector('.information-panel-toggle-text')\n if (text) {\n text.textContent = this.state.active ? '閉じる' : '開く'\n }\n }\n\n // コンテンツの状態更新\n if (this.contentElement) {\n const contentInner = this.contentElement.querySelector('.information-panel-content')\n\n if (this.state.active) {\n this.contentElement.classList.add('is-active')\n contentInner?.removeAttribute('hidden')\n } else {\n this.contentElement.classList.remove('is-active')\n // アニメーション終了後にhiddenを設定\n setTimeout(() => {\n if (!this.state.active) {\n contentInner?.setAttribute('hidden', '')\n }\n }, 200)\n }\n }\n }\n\n // ===========================================================================\n // Static Field Renderer\n // ===========================================================================\n\n static renderField(field: InputField): string {\n const infoField = field as InputField & {\n variant?: 'info' | 'success' | 'warning' | 'error'\n }\n const variant = infoField.variant ?? 'info'\n\n const infoHtml = `\n <div class=\"mokkun-information-panel panel-${variant}\">\n <div class=\"panel-icon\">ℹ️</div>\n <div class=\"panel-content\">\n <div class=\"panel-title\">${escapeHtml(field.label)}</div>\n ${field.description ? `<div class=\"panel-description\">${escapeHtml(field.description)}</div>` : ''}\n </div>\n </div>\n `\n return createFieldWrapper(field, infoHtml)\n }\n}\n\n// =============================================================================\n// Factory Function\n// =============================================================================\n\n/**\n * 情報パネルを作成\n */\nexport function createInformationPanel(\n container: HTMLElement,\n config: InformationPanelConfig,\n callbacks: InformationPanelCallbacks = {}\n): InformationPanel {\n const panel = new InformationPanel(container, config, callbacks)\n panel.render()\n return panel\n}\n","/**\n * Dropdown Component\n * ドロップダウンコンポーネント\n *\n * 3つのバリアント:\n * - MenuButton: アクションメニュー\n * - FilterDropdown: フィルター操作\n * - SortDropdown: 並び替え操作\n */\n\nimport { createElement, generateId } from '../utils/dom'\nimport { escapeHtml, createFieldWrapper } from '../utils/field-helpers'\nimport type { InputField } from '../../types/schema'\n\n// =============================================================================\n// Types\n// =============================================================================\n\n/**\n * ドロップダウンメニュー項目の基本型\n */\ninterface BaseMenuItem {\n /** 項目ID */\n id: string\n /** 項目ラベル */\n label: string\n /** アイコン(オプション) */\n icon?: string\n /** 無効化 */\n disabled?: boolean\n}\n\n/**\n * アクションメニュー項目\n */\nexport interface ActionMenuItem extends BaseMenuItem {\n type: 'action'\n /** クリック時のハンドラー */\n onAction?: (id: string) => void\n}\n\n/**\n * 区切り線\n */\nexport interface DividerMenuItem {\n type: 'divider'\n /** 一意なID(必須) */\n id: string\n}\n\n/**\n * フィルター項目\n */\nexport interface FilterMenuItem extends BaseMenuItem {\n type: 'filter'\n /** フィルター値 */\n value: string\n /** 選択状態 */\n selected?: boolean\n}\n\n/**\n * ソート項目\n */\nexport interface SortMenuItem extends BaseMenuItem {\n type: 'sort'\n /** ソートフィールド */\n field: string\n /** ソート方向 */\n direction?: 'asc' | 'desc'\n}\n\n/**\n * 全てのメニュー項目のユニオン型\n */\nexport type MenuItem = ActionMenuItem | DividerMenuItem | FilterMenuItem | SortMenuItem\n\n/**\n * ドロップダウンのバリアント\n */\nexport type DropdownVariant = 'menu' | 'filter' | 'sort'\n\n/**\n * ドロップダウンの配置\n */\nexport type DropdownPlacement = 'bottom-start' | 'bottom-end' | 'top-start' | 'top-end'\n\n/**\n * ドロップダウンの状態\n */\nexport interface DropdownState {\n /** 開閉状態 */\n isOpen: boolean\n /** メニュー項目 */\n items: MenuItem[]\n /** 選択されたフィルター(FilterDropdown用) */\n selectedFilters?: string[]\n /** 現在のソート(SortDropdown用) */\n currentSort?: {\n field: string\n direction: 'asc' | 'desc'\n }\n /** フォーカスされている項目のインデックス */\n focusedIndex: number\n}\n\n/**\n * ドロップダウンのコールバック\n */\nexport interface DropdownCallbacks {\n /** 開閉状態変更時 */\n onOpenChange?: (isOpen: boolean) => void\n /** メニュー項目選択時 */\n onSelect?: (item: MenuItem) => void\n /** フィルター適用時(FilterDropdown用) */\n onApply?: (selectedFilters: string[]) => void\n /** フィルタークリア時(FilterDropdown用) */\n onReset?: () => void\n /** ソート変更時(SortDropdown用) */\n onSortChange?: (field: string, direction: 'asc' | 'desc') => void\n}\n\n/**\n * ドロップダウンの設定\n */\nexport interface DropdownConfig {\n /** バリアント */\n variant?: DropdownVariant\n /** トリガーボタンのラベル */\n triggerLabel: string\n /** トリガーボタンのアイコン */\n triggerIcon?: string\n /** メニュー項目 */\n items: MenuItem[]\n /** 配置 */\n placement?: DropdownPlacement\n /** トリガーサイズ */\n triggerSize?: 's' | 'default'\n /** アイコンのみのトリガー */\n onlyIconTrigger?: boolean\n /** 初期開閉状態 */\n defaultOpen?: boolean\n /** フィルター状態(FilterDropdown用) */\n isFiltered?: boolean\n /** モーダル表示(モバイル用、将来実装) */\n useModal?: boolean\n}\n\n// =============================================================================\n// Dropdown Class\n// =============================================================================\n\n/**\n * ドロップダウンコンポーネント\n */\nexport class Dropdown {\n private config: DropdownConfig\n private state: DropdownState\n private callbacks: DropdownCallbacks\n private container: HTMLElement\n private instanceId: string\n private triggerElement: HTMLElement | null = null\n private contentElement: HTMLElement | null = null\n private clickOutsideHandler: ((e: MouseEvent) => void) | null = null\n private keyboardHandler: ((e: KeyboardEvent) => void) | null = null\n\n constructor(\n container: HTMLElement,\n config: DropdownConfig,\n callbacks: DropdownCallbacks = {}\n ) {\n this.config = config\n this.container = container\n this.callbacks = callbacks\n this.instanceId = generateId('dropdown')\n this.state = this.createInitialState()\n }\n\n // ===========================================================================\n // Public Methods\n // ===========================================================================\n\n /**\n * ドロップダウンをレンダリング\n */\n render(): void {\n this.container.innerHTML = ''\n\n const variant = this.config.variant ?? 'menu'\n const placement = this.config.placement ?? 'bottom-start'\n const triggerSize = this.config.triggerSize ?? 'default'\n\n this.container.className = `mokkun-dropdown dropdown-${variant} dropdown-${placement} dropdown-trigger-${triggerSize}`\n // Ensure overflow is visible for dropdown menu to be visible outside container\n this.container.style.overflow = 'visible'\n\n if (this.state.isOpen) {\n this.container.setAttribute('data-state', 'open')\n } else {\n this.container.setAttribute('data-state', 'closed')\n }\n\n const wrapper = createElement('div', { className: 'dropdown-wrapper' })\n\n // トリガーボタン\n this.triggerElement = this.renderTrigger()\n wrapper.appendChild(this.triggerElement)\n\n // ドロップダウンコンテンツ\n if (this.state.isOpen) {\n this.contentElement = this.renderContent()\n wrapper.appendChild(this.contentElement)\n this.attachEventListeners()\n\n // 初回オープン時に最初の項目にフォーカスを設定(再レンダリングなし)\n if (this.state.focusedIndex === -1) {\n this.initializeFocus()\n }\n } else {\n this.contentElement = null\n this.detachEventListeners()\n }\n\n this.container.appendChild(wrapper)\n }\n\n /**\n * 開閉状態を切り替え\n */\n toggle(): void {\n this.setOpen(!this.state.isOpen)\n }\n\n /**\n * 開く\n */\n open(): void {\n this.setOpen(true)\n }\n\n /**\n * 閉じる\n */\n close(): void {\n this.setOpen(false)\n }\n\n /**\n * 開閉状態を設定\n */\n setOpen(isOpen: boolean): void {\n if (this.state.isOpen === isOpen) {\n return\n }\n\n this.state = {\n ...this.state,\n isOpen,\n focusedIndex: -1,\n }\n\n this.render()\n this.callbacks.onOpenChange?.(isOpen)\n }\n\n /**\n * 状態を取得\n */\n getState(): DropdownState {\n return { ...this.state }\n }\n\n /**\n * メニュー項目を更新\n */\n setItems(items: MenuItem[]): void {\n this.state = {\n ...this.state,\n items,\n }\n\n if (this.state.isOpen) {\n this.render()\n }\n }\n\n /**\n * コンポーネントを破棄\n */\n destroy(): void {\n this.detachEventListeners()\n this.container.innerHTML = ''\n }\n\n // ===========================================================================\n // Private Methods - Initialization\n // ===========================================================================\n\n private createInitialState(): DropdownState {\n const defaultOpen = this.config.defaultOpen ?? false\n\n return {\n isOpen: defaultOpen,\n items: this.config.items,\n selectedFilters:\n this.config.variant === 'filter'\n ? this.config.items\n .filter((item): item is FilterMenuItem => item.type === 'filter' && item.selected === true)\n .map((item) => item.value)\n : undefined,\n currentSort: undefined,\n focusedIndex: -1,\n }\n }\n\n // ===========================================================================\n // Private Methods - Rendering\n // ===========================================================================\n\n private renderTrigger(): HTMLElement {\n const onlyIcon = this.config.onlyIconTrigger ?? false\n const triggerSize = this.config.triggerSize ?? 'default'\n const isFiltered = this.config.isFiltered ?? false\n\n const button = createElement('button', {\n className: `dropdown-trigger dropdown-trigger-${triggerSize}${isFiltered ? ' is-filtered' : ''}`,\n attributes: {\n type: 'button',\n 'aria-haspopup': 'true',\n 'aria-expanded': String(this.state.isOpen),\n 'aria-controls': `${this.instanceId}-content`,\n id: `${this.instanceId}-trigger`,\n },\n })\n\n // アイコン\n if (this.config.triggerIcon) {\n const icon = createElement('span', {\n className: 'dropdown-trigger-icon',\n })\n icon.innerHTML = this.config.triggerIcon\n button.appendChild(icon)\n }\n\n // ラベル(アイコンのみモードでは非表示)\n if (!onlyIcon) {\n const label = createElement('span', {\n className: 'dropdown-trigger-label',\n textContent: this.config.triggerLabel,\n })\n button.appendChild(label)\n }\n\n // キャレット(下向き矢印)\n const caret = createElement('span', {\n className: 'dropdown-trigger-caret',\n textContent: '▼',\n })\n caret.setAttribute('aria-hidden', 'true')\n button.appendChild(caret)\n\n button.addEventListener('click', () => {\n this.toggle()\n })\n\n return button\n }\n\n private renderContent(): HTMLElement {\n const variant = this.config.variant ?? 'menu'\n const placement = this.config.placement ?? 'bottom-start'\n\n const content = createElement('div', {\n className: `dropdown-content dropdown-content-${placement}`,\n attributes: {\n role: 'menu',\n 'aria-labelledby': `${this.instanceId}-trigger`,\n id: `${this.instanceId}-content`,\n },\n })\n\n if (variant === 'filter') {\n this.renderFilterContent(content)\n } else {\n this.renderMenuContent(content)\n }\n\n return content\n }\n\n private renderMenuContent(container: HTMLElement): void {\n const menu = createElement('div', { className: 'dropdown-menu', attributes: { role: 'menu' } })\n\n this.state.items.forEach((item, index) => {\n if (item.type === 'divider') {\n menu.appendChild(this.renderDivider())\n } else {\n menu.appendChild(this.renderMenuItem(item, index))\n }\n })\n\n container.appendChild(menu)\n }\n\n private renderFilterContent(container: HTMLElement): void {\n const filterContent = createElement('div', { className: 'dropdown-filter-content' })\n\n // フィルター項目\n const menu = createElement('div', { className: 'dropdown-menu', attributes: { role: 'menu' } })\n\n const filterItems = this.state.items.filter((item): item is FilterMenuItem => item.type === 'filter')\n\n filterItems.forEach((item, index) => {\n menu.appendChild(this.renderFilterItem(item, index))\n })\n\n filterContent.appendChild(menu)\n\n // アクションボタン\n const actions = createElement('div', { className: 'dropdown-filter-actions' })\n\n const resetButton = createElement('button', {\n className: 'dropdown-filter-button dropdown-filter-reset',\n textContent: 'クリア',\n attributes: { type: 'button' },\n })\n\n resetButton.addEventListener('click', () => {\n this.handleFilterReset()\n })\n\n const applyButton = createElement('button', {\n className: 'dropdown-filter-button dropdown-filter-apply',\n textContent: '適用',\n attributes: { type: 'button' },\n })\n\n applyButton.addEventListener('click', () => {\n this.handleFilterApply()\n })\n\n actions.appendChild(resetButton)\n actions.appendChild(applyButton)\n\n filterContent.appendChild(actions)\n container.appendChild(filterContent)\n }\n\n private renderMenuItem(item: ActionMenuItem | FilterMenuItem | SortMenuItem, index: number): HTMLElement {\n const menuItem = createElement('div', {\n className: `dropdown-menu-item${item.disabled ? ' is-disabled' : ''}${this.state.focusedIndex === index ? ' is-focused' : ''}`,\n attributes: {\n role: 'menuitem',\n tabindex: String(item.disabled ? -1 : 0),\n 'aria-disabled': item.disabled ? 'true' : 'false',\n 'data-index': String(index),\n },\n })\n\n // アイコン\n if (item.icon) {\n const icon = createElement('span', {\n className: 'dropdown-menu-item-icon',\n })\n icon.innerHTML = item.icon\n menuItem.appendChild(icon)\n }\n\n // ラベル\n const label = createElement('span', {\n className: 'dropdown-menu-item-label',\n textContent: item.label,\n })\n menuItem.appendChild(label)\n\n // ソート方向インジケーター(SortDropdown用)\n if (item.type === 'sort' && this.state.currentSort?.field === item.field) {\n const indicator = createElement('span', {\n className: 'dropdown-menu-item-sort-indicator',\n textContent: this.state.currentSort.direction === 'asc' ? '↑' : '↓',\n })\n menuItem.appendChild(indicator)\n }\n\n if (!item.disabled) {\n menuItem.addEventListener('click', () => {\n this.handleItemClick(item)\n })\n }\n\n return menuItem\n }\n\n private renderFilterItem(item: FilterMenuItem, index: number): HTMLElement {\n const isSelected = this.state.selectedFilters?.includes(item.value) ?? false\n\n const menuItem = createElement('label', {\n className: `dropdown-menu-item dropdown-filter-item${item.disabled ? ' is-disabled' : ''}${isSelected ? ' is-selected' : ''}${this.state.focusedIndex === index ? ' is-focused' : ''}`,\n attributes: {\n tabindex: String(item.disabled ? -1 : 0),\n 'data-index': String(index),\n },\n })\n\n // チェックボックス\n const checkbox = createElement('input', {\n className: 'dropdown-filter-checkbox',\n attributes: {\n type: 'checkbox',\n value: item.value,\n },\n }) as HTMLInputElement\n\n if (isSelected) {\n checkbox.checked = true\n }\n\n if (item.disabled) {\n checkbox.disabled = true\n }\n\n checkbox.addEventListener('change', () => {\n this.handleFilterChange(item.value, checkbox.checked)\n })\n\n menuItem.appendChild(checkbox)\n\n // アイコン\n if (item.icon) {\n const icon = createElement('span', {\n className: 'dropdown-menu-item-icon',\n })\n icon.innerHTML = item.icon\n menuItem.appendChild(icon)\n }\n\n // ラベル\n const label = createElement('span', {\n className: 'dropdown-menu-item-label',\n textContent: item.label,\n })\n menuItem.appendChild(label)\n\n return menuItem\n }\n\n private renderDivider(): HTMLElement {\n return createElement('div', {\n className: 'dropdown-divider',\n attributes: {\n role: 'separator',\n },\n })\n }\n\n // ===========================================================================\n // Private Methods - Event Handlers\n // ===========================================================================\n\n private handleItemClick(item: MenuItem): void {\n if (item.type === 'divider') {\n return\n }\n\n this.callbacks.onSelect?.(item)\n\n if (item.type === 'action') {\n item.onAction?.(item.id)\n this.close()\n } else if (item.type === 'sort') {\n const newDirection = this.state.currentSort?.field === item.field && this.state.currentSort.direction === 'asc' ? 'desc' : 'asc'\n\n this.state = {\n ...this.state,\n currentSort: {\n field: item.field,\n direction: newDirection,\n },\n }\n\n this.callbacks.onSortChange?.(item.field, newDirection)\n this.close()\n }\n }\n\n private handleFilterChange(value: string, checked: boolean): void {\n const selectedFilters = this.state.selectedFilters ?? []\n\n if (checked) {\n this.state = {\n ...this.state,\n selectedFilters: [...selectedFilters, value],\n }\n } else {\n this.state = {\n ...this.state,\n selectedFilters: selectedFilters.filter((v) => v !== value),\n }\n }\n }\n\n private handleFilterApply(): void {\n this.callbacks.onApply?.(this.state.selectedFilters ?? [])\n this.close()\n }\n\n private handleFilterReset(): void {\n this.state = {\n ...this.state,\n selectedFilters: [],\n }\n\n this.render()\n this.callbacks.onReset?.()\n }\n\n private handleClickOutside(event: MouseEvent): void {\n const target = event.target as Node\n\n if (!this.container.contains(target)) {\n this.close()\n }\n }\n\n private handleKeyboard(event: KeyboardEvent): void {\n if (!this.state.isOpen) {\n return\n }\n\n const actionableItems = this.state.items.filter(\n (item) => item.type !== 'divider' && !(item as ActionMenuItem).disabled\n )\n\n switch (event.key) {\n case 'Escape':\n event.preventDefault()\n this.close()\n this.triggerElement?.focus()\n break\n\n case 'ArrowDown':\n event.preventDefault()\n this.focusNextItem(actionableItems.length)\n break\n\n case 'ArrowUp':\n event.preventDefault()\n this.focusPreviousItem(actionableItems.length)\n break\n\n case 'Home':\n event.preventDefault()\n this.focusFirstItem()\n break\n\n case 'End':\n event.preventDefault()\n this.focusLastItem(actionableItems.length)\n break\n\n case 'Enter':\n case ' ':\n event.preventDefault()\n this.selectFocusedItem()\n break\n }\n }\n\n // ===========================================================================\n // Private Methods - Focus Management\n // ===========================================================================\n\n /**\n * 初回オープン時のフォーカス設定(再レンダリングなし)\n */\n private initializeFocus(): void {\n const actionableItems = this.state.items.filter(\n (item) => item.type !== 'divider' && !(item as ActionMenuItem).disabled\n )\n\n if (actionableItems.length === 0) {\n return\n }\n\n const firstIndex = this.state.items.indexOf(actionableItems[0])\n\n // 状態を更新するが、再レンダリングしない\n this.state = {\n ...this.state,\n focusedIndex: firstIndex,\n }\n\n // DOMが構築された後にフォーカスを移動\n const focusedElement = this.contentElement?.querySelector(`[data-index=\"${firstIndex}\"]`) as HTMLElement\n focusedElement?.focus()\n }\n\n private focusFirstItem(): void {\n const actionableItems = this.state.items.filter(\n (item) => item.type !== 'divider' && !(item as ActionMenuItem).disabled\n )\n\n if (actionableItems.length === 0) {\n return\n }\n\n const firstIndex = this.state.items.indexOf(actionableItems[0])\n this.setFocusedIndex(firstIndex)\n }\n\n private focusLastItem(actionableCount: number): void {\n if (actionableCount === 0) {\n return\n }\n\n const actionableItems = this.state.items.filter(\n (item) => item.type !== 'divider' && !(item as ActionMenuItem).disabled\n )\n\n const lastIndex = this.state.items.indexOf(actionableItems[actionableItems.length - 1])\n this.setFocusedIndex(lastIndex)\n }\n\n private focusNextItem(actionableCount: number): void {\n if (actionableCount === 0) {\n return\n }\n\n const actionableItems = this.state.items.filter(\n (item) => item.type !== 'divider' && !(item as ActionMenuItem).disabled\n )\n\n const currentActionableIndex = actionableItems.findIndex((item) => this.state.items.indexOf(item) === this.state.focusedIndex)\n\n const nextActionableIndex = (currentActionableIndex + 1) % actionableCount\n const nextIndex = this.state.items.indexOf(actionableItems[nextActionableIndex])\n\n this.setFocusedIndex(nextIndex)\n }\n\n private focusPreviousItem(actionableCount: number): void {\n if (actionableCount === 0) {\n return\n }\n\n const actionableItems = this.state.items.filter(\n (item) => item.type !== 'divider' && !(item as ActionMenuItem).disabled\n )\n\n const currentActionableIndex = actionableItems.findIndex((item) => this.state.items.indexOf(item) === this.state.focusedIndex)\n\n const previousActionableIndex = currentActionableIndex <= 0 ? actionableCount - 1 : currentActionableIndex - 1\n const previousIndex = this.state.items.indexOf(actionableItems[previousActionableIndex])\n\n this.setFocusedIndex(previousIndex)\n }\n\n private setFocusedIndex(index: number): void {\n this.state = {\n ...this.state,\n focusedIndex: index,\n }\n\n this.render()\n\n // フォーカスされた要素にフォーカスを移動\n const focusedElement = this.contentElement?.querySelector(`[data-index=\"${index}\"]`) as HTMLElement\n focusedElement?.focus()\n }\n\n private selectFocusedItem(): void {\n if (this.state.focusedIndex === -1) {\n return\n }\n\n const item = this.state.items[this.state.focusedIndex]\n\n if (item && item.type !== 'divider') {\n this.handleItemClick(item)\n }\n }\n\n // ===========================================================================\n // Private Methods - Event Listeners\n // ===========================================================================\n\n private attachEventListeners(): void {\n this.clickOutsideHandler = this.handleClickOutside.bind(this)\n this.keyboardHandler = this.handleKeyboard.bind(this)\n\n setTimeout(() => {\n document.addEventListener('click', this.clickOutsideHandler!)\n document.addEventListener('keydown', this.keyboardHandler!)\n }, 0)\n }\n\n private detachEventListeners(): void {\n if (this.clickOutsideHandler) {\n document.removeEventListener('click', this.clickOutsideHandler)\n this.clickOutsideHandler = null\n }\n\n if (this.keyboardHandler) {\n document.removeEventListener('keydown', this.keyboardHandler)\n this.keyboardHandler = null\n }\n }\n\n // ===========================================================================\n // Static Field Renderer\n // ===========================================================================\n\n static renderField(field: InputField): string {\n const dropdownField = field as InputField & {\n options?: Array<{ value: string; label: string }>\n }\n const options = dropdownField.options ?? []\n\n const dropdownHtml = `\n <div class=\"mokkun-dropdown\">\n <button type=\"button\" class=\"dropdown-trigger\" aria-haspopup=\"listbox\" aria-expanded=\"false\">\n <span>${escapeHtml(field.label)}</span>\n <span class=\"dropdown-arrow\">▼</span>\n </button>\n <ul class=\"dropdown-menu\" role=\"listbox\" hidden>\n ${options.map(opt => `\n <li class=\"dropdown-item\" role=\"option\" data-value=\"${escapeHtml(opt.value)}\">\n ${escapeHtml(opt.label)}\n </li>\n `).join('')}\n </ul>\n </div>\n `\n return createFieldWrapper(field, dropdownHtml)\n }\n}\n\n// =============================================================================\n// Factory Functions\n// =============================================================================\n\n/**\n * ドロップダウンを作成(ファクトリー関数)\n */\nexport function createDropdown(\n container: HTMLElement,\n config: DropdownConfig,\n callbacks?: DropdownCallbacks\n): Dropdown {\n const dropdown = new Dropdown(container, config, callbacks)\n dropdown.render()\n return dropdown\n}\n\n/**\n * メニューボタンを作成\n */\nexport function createMenuButton(\n container: HTMLElement,\n config: Omit<DropdownConfig, 'variant'>,\n callbacks?: DropdownCallbacks\n): Dropdown {\n return createDropdown(container, { ...config, variant: 'menu' }, callbacks)\n}\n\n/**\n * フィルタードロップダウンを作成\n */\nexport function createFilterDropdown(\n container: HTMLElement,\n config: Omit<DropdownConfig, 'variant'>,\n callbacks?: DropdownCallbacks\n): Dropdown {\n return createDropdown(container, { ...config, variant: 'filter' }, callbacks)\n}\n\n/**\n * ソートドロップダウンを作成\n */\nexport function createSortDropdown(\n container: HTMLElement,\n config: Omit<DropdownConfig, 'variant'>,\n callbacks?: DropdownCallbacks\n): Dropdown {\n return createDropdown(container, { ...config, variant: 'sort' }, callbacks)\n}\n","/**\n * Delete Confirm Dialog Component\n * 削除確認ダイアログ - 依存データの影響を表示\n */\n\nimport { createElement, generateId } from '../utils/dom'\nimport { escapeHtml, createFieldWrapper } from '../utils/field-helpers'\nimport type { InputField } from '../../types/schema'\n\n// =============================================================================\n// Types\n// =============================================================================\n\n/**\n * 依存データの情報\n */\nexport interface DependencyInfo {\n /** 依存データのタイプ(例:spaces, reservations) */\n type: string\n /** 表示ラベル */\n label: string\n /** 件数 */\n count: number\n}\n\n/**\n * 削除確認ダイアログの設定\n */\nexport interface DeleteConfirmDialogConfig {\n /** ダイアログタイトル */\n title: string\n /** 削除対象の名前(例:施設名) */\n targetName: string\n /** 削除対象のタイプ(例:施設) */\n targetType?: string\n /** 依存データの情報 */\n dependencies?: DependencyInfo[]\n /** 警告メッセージ */\n warningMessage?: string\n /** 確認ボタンのラベル */\n confirmLabel?: string\n /** キャンセルボタンのラベル */\n cancelLabel?: string\n /** 危険なアクションとしてスタイリング */\n danger?: boolean\n}\n\n/**\n * ダイアログのコールバック\n */\nexport interface DeleteConfirmDialogCallbacks {\n /** 削除確認時 */\n onConfirm?: () => void\n /** キャンセル時 */\n onCancel?: () => void\n /** ダイアログクローズ時 */\n onClose?: () => void\n}\n\n/**\n * ダイアログの状態\n */\nexport interface DeleteConfirmDialogState {\n /** ダイアログが開いているか */\n isOpen: boolean\n /** フォーカスを戻す要素 */\n previouslyFocusedElement: Element | null\n}\n\n// =============================================================================\n// DeleteConfirmDialog Class\n// =============================================================================\n\n/**\n * 削除確認ダイアログコンポーネント\n */\nexport class DeleteConfirmDialog {\n private config: DeleteConfirmDialogConfig\n private callbacks: DeleteConfirmDialogCallbacks\n private state: DeleteConfirmDialogState\n private dialogElement: HTMLElement | null = null\n private overlayElement: HTMLElement | null = null\n private readonly dialogId: string\n private boundKeydownHandler: (e: KeyboardEvent) => void\n\n constructor(\n config: DeleteConfirmDialogConfig,\n callbacks: DeleteConfirmDialogCallbacks = {}\n ) {\n this.config = config\n this.callbacks = callbacks\n this.dialogId = generateId('delete-dialog')\n this.state = {\n isOpen: false,\n previouslyFocusedElement: null,\n }\n this.boundKeydownHandler = this.handleKeydown.bind(this)\n }\n\n // ===========================================================================\n // Public Methods\n // ===========================================================================\n\n /**\n * ダイアログを開く\n */\n open(): void {\n if (this.state.isOpen) {\n return\n }\n\n this.state = {\n ...this.state,\n isOpen: true,\n previouslyFocusedElement: document.activeElement,\n }\n\n this.render()\n this.setupEventListeners()\n this.trapFocus()\n }\n\n /**\n * ダイアログを閉じる\n */\n close(): void {\n if (!this.state.isOpen) {\n return\n }\n\n this.removeEventListeners()\n this.destroy()\n\n // フォーカスを元の要素に戻す\n if (this.state.previouslyFocusedElement instanceof HTMLElement) {\n this.state.previouslyFocusedElement.focus()\n }\n\n this.state = {\n ...this.state,\n isOpen: false,\n previouslyFocusedElement: null,\n }\n\n this.callbacks.onClose?.()\n }\n\n /**\n * 設定を更新\n */\n updateConfig(config: Partial<DeleteConfirmDialogConfig>): void {\n this.config = {\n ...this.config,\n ...config,\n }\n\n if (this.state.isOpen) {\n this.render()\n }\n }\n\n /**\n * 現在の状態を取得\n */\n getState(): DeleteConfirmDialogState {\n return { ...this.state }\n }\n\n /**\n * ダイアログ要素を取得(テスト用)\n */\n getDialogElement(): HTMLElement | null {\n return this.dialogElement\n }\n\n // ===========================================================================\n // Private Methods - Rendering\n // ===========================================================================\n\n /**\n * ダイアログをレンダリング\n */\n private render(): void {\n this.destroy()\n\n // オーバーレイ\n this.overlayElement = createElement('div', {\n className: 'dialog-overlay',\n attributes: {\n 'data-dialog-overlay': this.dialogId,\n },\n })\n\n // ダイアログコンテナ\n const dangerClass = this.config.danger !== false ? 'dialog-danger' : ''\n this.dialogElement = createElement('div', {\n className: `delete-confirm-dialog ${dangerClass}`.trim(),\n attributes: {\n 'role': 'alertdialog',\n 'aria-modal': 'true',\n 'aria-labelledby': `${this.dialogId}-title`,\n 'aria-describedby': `${this.dialogId}-description`,\n 'data-dialog-id': this.dialogId,\n },\n })\n\n // ダイアログ内容を構築\n this.dialogElement.appendChild(this.renderHeader())\n this.dialogElement.appendChild(this.renderBody())\n this.dialogElement.appendChild(this.renderFooter())\n\n // DOMに追加\n document.body.appendChild(this.overlayElement)\n document.body.appendChild(this.dialogElement)\n\n // body のスクロールを防止\n document.body.classList.add('dialog-open')\n }\n\n /**\n * ヘッダーをレンダリング\n */\n private renderHeader(): HTMLElement {\n const header = createElement('div', { className: 'dialog-header' })\n\n // 警告アイコン\n const icon = createElement('div', { className: 'dialog-icon' })\n icon.innerHTML = `\n <svg viewBox=\"0 0 24 24\" width=\"24\" height=\"24\" fill=\"currentColor\" aria-hidden=\"true\">\n <path d=\"M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm1 15h-2v-2h2v2zm0-4h-2V7h2v6z\"/>\n </svg>\n `\n header.appendChild(icon)\n\n // タイトル\n const title = createElement('h2', {\n className: 'dialog-title',\n textContent: this.config.title,\n attributes: {\n 'id': `${this.dialogId}-title`,\n },\n })\n header.appendChild(title)\n\n return header\n }\n\n /**\n * ボディをレンダリング\n */\n private renderBody(): HTMLElement {\n const body = createElement('div', {\n className: 'dialog-body',\n attributes: {\n 'id': `${this.dialogId}-description`,\n },\n })\n\n // 削除対象の情報\n const targetInfo = createElement('div', { className: 'dialog-target-info' })\n const targetTypeLabel = this.config.targetType ?? '項目'\n const targetText = createElement('p', {\n className: 'dialog-target-text',\n })\n targetText.innerHTML = `<strong>${this.escapeHtml(targetTypeLabel)}</strong>: ${this.escapeHtml(this.config.targetName)}`\n targetInfo.appendChild(targetText)\n body.appendChild(targetInfo)\n\n // 依存データの表示\n if (this.config.dependencies && this.config.dependencies.length > 0) {\n const dependenciesSection = this.renderDependencies()\n body.appendChild(dependenciesSection)\n }\n\n // 警告メッセージ\n if (this.config.warningMessage) {\n const warning = createElement('div', {\n className: 'dialog-warning',\n attributes: {\n 'role': 'alert',\n },\n })\n const warningIcon = createElement('span', { className: 'warning-icon' })\n warningIcon.innerHTML = `\n <svg viewBox=\"0 0 24 24\" width=\"16\" height=\"16\" fill=\"currentColor\" aria-hidden=\"true\">\n <path d=\"M1 21h22L12 2 1 21zm12-3h-2v-2h2v2zm0-4h-2v-4h2v4z\"/>\n </svg>\n `\n warning.appendChild(warningIcon)\n const warningText = createElement('span', {\n className: 'warning-text',\n textContent: this.config.warningMessage,\n })\n warning.appendChild(warningText)\n body.appendChild(warning)\n }\n\n return body\n }\n\n /**\n * 依存データセクションをレンダリング\n */\n private renderDependencies(): HTMLElement {\n const section = createElement('div', { className: 'dialog-dependencies' })\n\n const heading = createElement('h3', {\n className: 'dependencies-heading',\n textContent: '関連データへの影響',\n })\n section.appendChild(heading)\n\n const list = createElement('ul', { className: 'dependencies-list' })\n\n for (const dep of this.config.dependencies ?? []) {\n const item = createElement('li', { className: 'dependency-item' })\n const label = createElement('span', {\n className: 'dependency-label',\n textContent: dep.label,\n })\n const count = createElement('span', {\n className: `dependency-count ${dep.count > 0 ? 'has-data' : ''}`,\n textContent: `${dep.count}件`,\n })\n item.appendChild(label)\n item.appendChild(count)\n list.appendChild(item)\n }\n\n section.appendChild(list)\n\n // 影響説明\n const hasAffectedData = this.config.dependencies?.some(d => d.count > 0)\n if (hasAffectedData) {\n const affectedNote = createElement('p', {\n className: 'dependencies-note',\n textContent: 'これらの関連データも削除されます。この操作は取り消せません。',\n })\n section.appendChild(affectedNote)\n }\n\n return section\n }\n\n /**\n * フッターをレンダリング\n */\n private renderFooter(): HTMLElement {\n const footer = createElement('div', { className: 'dialog-footer' })\n\n // キャンセルボタン\n const cancelBtn = createElement('button', {\n className: 'dialog-btn dialog-btn-cancel',\n textContent: this.config.cancelLabel ?? 'キャンセル',\n attributes: {\n 'type': 'button',\n 'data-action': 'cancel',\n },\n })\n cancelBtn.addEventListener('click', () => this.handleCancel())\n footer.appendChild(cancelBtn)\n\n // 削除ボタン\n const confirmBtn = createElement('button', {\n className: 'dialog-btn dialog-btn-confirm dialog-btn-danger',\n textContent: this.config.confirmLabel ?? '削除を実行',\n attributes: {\n 'type': 'button',\n 'data-action': 'confirm',\n },\n })\n confirmBtn.addEventListener('click', () => this.handleConfirm())\n footer.appendChild(confirmBtn)\n\n return footer\n }\n\n // ===========================================================================\n // Private Methods - Event Handling\n // ===========================================================================\n\n /**\n * イベントリスナーを設定\n */\n private setupEventListeners(): void {\n document.addEventListener('keydown', this.boundKeydownHandler)\n\n // オーバーレイクリックで閉じる\n this.overlayElement?.addEventListener('click', () => this.handleCancel())\n }\n\n /**\n * イベントリスナーを削除\n */\n private removeEventListeners(): void {\n document.removeEventListener('keydown', this.boundKeydownHandler)\n }\n\n /**\n * キーボードイベントハンドラ\n */\n private handleKeydown(e: KeyboardEvent): void {\n if (e.key === 'Escape') {\n e.preventDefault()\n this.handleCancel()\n return\n }\n\n // Tab キーでフォーカストラップ\n if (e.key === 'Tab') {\n this.handleTabKey(e)\n }\n }\n\n /**\n * Tab キーの処理(フォーカストラップ)\n */\n private handleTabKey(e: KeyboardEvent): void {\n if (!this.dialogElement) {\n return\n }\n\n const focusableElements = this.getFocusableElements()\n if (focusableElements.length === 0) {\n return\n }\n\n const firstElement = focusableElements[0]\n const lastElement = focusableElements[focusableElements.length - 1]\n const activeElement = document.activeElement\n\n if (e.shiftKey) {\n // Shift+Tab: 最初の要素にいたら最後へ\n if (activeElement === firstElement) {\n e.preventDefault()\n lastElement.focus()\n }\n } else {\n // Tab: 最後の要素にいたら最初へ\n if (activeElement === lastElement) {\n e.preventDefault()\n firstElement.focus()\n }\n }\n }\n\n /**\n * フォーカス可能な要素を取得\n */\n private getFocusableElements(): HTMLElement[] {\n if (!this.dialogElement) {\n return []\n }\n\n const selector = [\n 'button:not([disabled])',\n 'a[href]',\n 'input:not([disabled])',\n 'select:not([disabled])',\n 'textarea:not([disabled])',\n '[tabindex]:not([tabindex=\"-1\"])',\n ].join(', ')\n\n return Array.from(this.dialogElement.querySelectorAll<HTMLElement>(selector))\n }\n\n /**\n * フォーカスをダイアログ内に設定\n */\n private trapFocus(): void {\n const focusableElements = this.getFocusableElements()\n if (focusableElements.length > 0) {\n // 最初のフォーカス可能要素(キャンセルボタン)にフォーカス\n focusableElements[0].focus()\n }\n }\n\n /**\n * 確認ボタンクリック時\n */\n private handleConfirm(): void {\n this.callbacks.onConfirm?.()\n this.close()\n }\n\n /**\n * キャンセルボタンクリック時\n */\n private handleCancel(): void {\n this.callbacks.onCancel?.()\n this.close()\n }\n\n // ===========================================================================\n // Private Methods - Utility\n // ===========================================================================\n\n /**\n * ダイアログ要素を破棄\n */\n private destroy(): void {\n if (this.overlayElement) {\n this.overlayElement.remove()\n this.overlayElement = null\n }\n if (this.dialogElement) {\n this.dialogElement.remove()\n this.dialogElement = null\n }\n document.body.classList.remove('dialog-open')\n }\n\n /**\n * HTML特殊文字をエスケープ\n */\n private escapeHtml(text: string): string {\n const div = document.createElement('div')\n div.textContent = text\n return div.innerHTML\n }\n\n // ===========================================================================\n // Static Field Renderer\n // ===========================================================================\n\n static renderField(field: InputField): string {\n const dialogField = field as InputField & {\n title?: string\n message?: string\n cancelLabel?: string\n confirmLabel?: string\n targetName?: string\n }\n const title = dialogField.title ?? field.label ?? '削除確認'\n const message = dialogField.message ?? field.description ?? 'この操作は取り消せません。本当に削除しますか?'\n const cancelLabel = dialogField.cancelLabel ?? 'キャンセル'\n const confirmLabel = dialogField.confirmLabel ?? '削除する'\n const targetName = dialogField.targetName ?? ''\n\n const dialogHtml = `\n <div class=\"delete-confirm-dialog-preview\">\n <div class=\"dialog-header\">\n <h3>${escapeHtml(title)}</h3>\n </div>\n <div class=\"dialog-body\">\n ${targetName ? `<p class=\"dialog-target\"><strong>対象:</strong> ${escapeHtml(targetName)}</p>` : ''}\n <p class=\"dialog-message\">${escapeHtml(message)}</p>\n </div>\n <div class=\"dialog-footer\">\n <button type=\"button\" class=\"dialog-button dialog-cancel\">${escapeHtml(cancelLabel)}</button>\n <button type=\"button\" class=\"dialog-button dialog-confirm dialog-danger\">${escapeHtml(confirmLabel)}</button>\n </div>\n </div>\n `\n return createFieldWrapper(field, dialogHtml)\n }\n}\n","/**\n * Dummy Data Generator\n * リピーター用のダミーデータ自動生成\n */\n\nimport type { InputField, SelectOption } from '../../types'\n\n/**\n * フィールドタイプに応じたダミーデータを生成\n */\nexport function generateDummyData(field: InputField, index: number = 0): unknown {\n switch (field.type) {\n case 'text':\n return generateTextDummy(field.input_type, field.id, index)\n\n case 'number':\n return generateNumberDummy(field.min, field.max, index)\n\n case 'textarea':\n return `Sample text content ${index + 1}`\n\n case 'select':\n return getFirstOptionValue(field.options)\n\n case 'multi_select':\n return getFirstOptionValueAsArray(field.options)\n\n case 'radio_group':\n return getFirstOptionValue(field.options)\n\n case 'checkbox_group':\n return getFirstOptionValueAsArray(field.options)\n\n case 'date_picker':\n return generateDateDummy(index)\n\n case 'time_picker':\n return generateTimeDummy(index)\n\n case 'duration_picker':\n return 3600 // 1 hour in seconds\n\n case 'duration_input':\n return '01:00:00'\n\n case 'file_upload':\n return null\n\n case 'repeater':\n // ネストされたリピーターの場合、空の配列を返す\n return []\n\n default:\n return null\n }\n}\n\n/**\n * テキスト用ダミーデータ\n */\nfunction generateTextDummy(\n inputType: string | undefined,\n fieldId: string,\n index: number\n): string {\n switch (inputType) {\n case 'email':\n return `user${index + 1}@example.com`\n case 'url':\n return `https://example.com/page${index + 1}`\n case 'tel':\n return `090-${String(1000 + index).padStart(4, '0')}-${String(1000 + index).padStart(4, '0')}`\n case 'password':\n return 'password123'\n default:\n return `${capitalizeFirst(fieldId)} ${index + 1}`\n }\n}\n\n/**\n * 数値用ダミーデータ\n */\nfunction generateNumberDummy(\n min: number | undefined,\n max: number | undefined,\n index: number\n): number {\n const minVal = min ?? 1\n const maxVal = max ?? 100\n return Math.min(minVal + index, maxVal)\n}\n\n/**\n * 日付用ダミーデータ\n */\nfunction generateDateDummy(index: number): string {\n const date = new Date()\n date.setDate(date.getDate() + index)\n return date.toISOString().split('T')[0]\n}\n\n/**\n * 時間用ダミーデータ\n */\nfunction generateTimeDummy(index: number): string {\n const hour = (9 + index) % 24\n return `${String(hour).padStart(2, '0')}:00`\n}\n\n/**\n * 選択肢から最初の値を取得\n */\nfunction getFirstOptionValue(\n options: SelectOption[] | string\n): string | number | null {\n if (typeof options === 'string') {\n return null\n }\n return options.length > 0 ? options[0].value : null\n}\n\n/**\n * 選択肢から最初の値を配列で取得\n */\nfunction getFirstOptionValueAsArray(\n options: SelectOption[] | string\n): (string | number)[] {\n if (typeof options === 'string') {\n return []\n }\n return options.length > 0 ? [options[0].value] : []\n}\n\n/**\n * 先頭を大文字にする\n */\nfunction capitalizeFirst(str: string): string {\n return str.charAt(0).toUpperCase() + str.slice(1).replace(/_/g, ' ')\n}\n\n/**\n * リピーターアイテム用のダミーデータセットを生成\n */\nexport function generateRepeaterItemDummyData(\n itemFields: InputField[],\n itemIndex: number\n): Record<string, unknown> {\n const data: Record<string, unknown> = {}\n for (const field of itemFields) {\n data[field.id] = generateDummyData(field, itemIndex)\n }\n return data\n}\n\n// =============================================================================\n// DataTable用ダミーデータ生成(Faker.js使用)\n// =============================================================================\n\n/**\n * Faker.jsのインターフェース(CDN版用)\n */\ninterface FakerInstance {\n locale?: string\n person: {\n fullName: () => string\n firstName: () => string\n lastName: () => string\n }\n internet: {\n email: () => string\n }\n phone: {\n number: () => string\n }\n location: {\n streetAddress: () => string\n state: () => string\n city: () => string\n zipCode: () => string\n }\n company: {\n name: () => string\n }\n commerce: {\n department: () => string\n }\n number: {\n int: (options?: { min?: number; max?: number }) => number\n }\n date: {\n recent: () => Date\n past: () => Date\n }\n string: {\n alphanumeric: (length: number) => string\n }\n lorem: {\n sentence: () => string\n words: (count: number) => string\n }\n}\n\n/**\n * グローバルのFaker.jsを取得(CDNで読み込まれた場合)\n */\nfunction getFaker(): FakerInstance | null {\n // CDNで読み込まれた場合、グローバルに `faker` が存在する\n if (typeof window !== 'undefined' && (window as unknown as Record<string, unknown>).faker) {\n return (window as unknown as Record<string, unknown>).faker as FakerInstance\n }\n return null\n}\n\n/**\n * カラムラベルに基づいてダミーデータを生成\n */\nfunction generateDummyValueForColumn(label: string, rowIndex: number): string | number {\n const faker = getFaker()\n const lowerLabel = label.toLowerCase()\n\n // Faker.jsが利用可能な場合\n if (faker) {\n // 日本語ロケールを設定(利用可能な場合)\n try {\n faker.locale = 'ja'\n } catch {\n // ロケール設定に失敗しても続行\n }\n\n // 名前関連\n if (lowerLabel.includes('名前') || lowerLabel.includes('氏名') || lowerLabel.includes('name')) {\n return faker.person.fullName()\n }\n if (lowerLabel.includes('姓') || lowerLabel.includes('苗字')) {\n return faker.person.lastName()\n }\n if (lowerLabel.includes('名') && !lowerLabel.includes('名前')) {\n return faker.person.firstName()\n }\n\n // 連絡先関連\n if (lowerLabel.includes('メール') || lowerLabel.includes('email')) {\n return faker.internet.email()\n }\n if (lowerLabel.includes('電話') || lowerLabel.includes('tel') || lowerLabel.includes('phone')) {\n return faker.phone.number()\n }\n\n // 住所関連\n if (lowerLabel.includes('住所') || lowerLabel.includes('address')) {\n return faker.location.streetAddress()\n }\n if (lowerLabel.includes('都道府県') || lowerLabel.includes('県')) {\n return faker.location.state()\n }\n if (lowerLabel.includes('市区町村') || lowerLabel.includes('市')) {\n return faker.location.city()\n }\n if (lowerLabel.includes('郵便番号') || lowerLabel.includes('zip')) {\n return faker.location.zipCode()\n }\n\n // 会社・ビジネス関連\n if (lowerLabel.includes('会社') || lowerLabel.includes('company') || lowerLabel.includes('施設')) {\n return faker.company.name()\n }\n if (lowerLabel.includes('部署') || lowerLabel.includes('department')) {\n return faker.commerce.department()\n }\n\n // 数値関連\n if (lowerLabel.includes('人数') || lowerLabel.includes('収容')) {\n return faker.number.int({ min: 1, max: 100 })\n }\n if (lowerLabel.includes('金額') || lowerLabel.includes('価格') || lowerLabel.includes('price')) {\n return faker.number.int({ min: 1000, max: 100000 })\n }\n if (lowerLabel.includes('広さ') || lowerLabel.includes('面積')) {\n return faker.number.int({ min: 10, max: 500 })\n }\n\n // 日付関連\n if (lowerLabel.includes('日付') || lowerLabel.includes('日時') || lowerLabel.includes('date')) {\n return faker.date.recent().toLocaleDateString('ja-JP')\n }\n if (lowerLabel.includes('作成日') || lowerLabel.includes('登録日')) {\n return faker.date.past().toLocaleDateString('ja-JP')\n }\n if (lowerLabel.includes('更新日')) {\n return faker.date.recent().toLocaleDateString('ja-JP')\n }\n\n // ステータス関連\n if (lowerLabel.includes('ステータス') || lowerLabel.includes('status') || lowerLabel.includes('状態')) {\n const statuses = ['有効', '無効', '保留中', '承認済み', '公開', '非公開', '下書き']\n return statuses[rowIndex % statuses.length]\n }\n\n // ID関連\n if (lowerLabel.includes('id') || lowerLabel.includes('番号')) {\n return faker.string.alphanumeric(8).toUpperCase()\n }\n\n // その他\n if (lowerLabel.includes('説明') || lowerLabel.includes('description')) {\n return faker.lorem.sentence()\n }\n if (lowerLabel.includes('備考') || lowerLabel.includes('メモ') || lowerLabel.includes('note')) {\n return faker.lorem.words(5)\n }\n\n // デフォルト: 短いテキスト\n return faker.lorem.words(2)\n }\n\n // Faker.jsが利用できない場合のフォールバック\n return `${label} ${rowIndex + 1}`\n}\n\n/**\n * DataTable用のダミー行データを生成\n */\nexport function generateDataTableDummyRow(\n columns: Array<{ id: string; label: string }>,\n rowIndex: number\n): Record<string, unknown> {\n const row: Record<string, unknown> = {\n id: rowIndex + 1,\n }\n\n for (const column of columns) {\n row[column.id] = generateDummyValueForColumn(column.label, rowIndex)\n }\n\n return row\n}\n\n/**\n * DataTable用のダミーデータセットを生成\n */\nexport function generateDataTableDummyData(\n columns: Array<{ id: string; label: string }>,\n rowCount: number = 10\n): Array<Record<string, unknown>> {\n const data: Array<Record<string, unknown>> = []\n\n for (let i = 0; i < rowCount; i++) {\n data.push(generateDataTableDummyRow(columns, i))\n }\n\n return data\n}\n","/**\n * Data Table Component\n * データテーブル(一覧表示)コンポーネント\n */\n\nimport type {\n DataTableField,\n DataTableColumn,\n DataTableRow,\n DataTableSortConfig,\n DataTableRowAction,\n DataTableFilterField,\n DataTableCellMerge,\n SelectOption,\n} from '../../types/schema'\nimport { generateDataTableDummyData } from '../utils/dummy-data'\n\n// =============================================================================\n// Types\n// =============================================================================\n\n/**\n * データテーブルの状態\n */\nexport interface DataTableState {\n /** 現在のデータ */\n data: DataTableRow[]\n /** 元のデータ(フィルタリング・ソート前) */\n originalData: DataTableRow[]\n /** 現在のソート設定 */\n sort: DataTableSortConfig | null\n /** 現在のフィルター値 */\n filterValues: Record<string, unknown>\n /** 選択された行ID */\n selectedRowIds: Set<string | number>\n /** 現在のページ(0始まり) */\n currentPage: number\n /** 1ページあたりの行数 */\n pageSize: number\n /** 総件数 */\n totalCount: number\n /** ローディング状態 */\n isLoading: boolean\n /** 折りたたまれたグループ名のセット */\n collapsedGroups: Set<string>\n /** カラム幅の状態(リサイズ用) */\n columnWidths: Record<string, number>\n}\n\n/**\n * データテーブルのコールバック\n */\nexport interface DataTableCallbacks {\n /** ソート変更時 */\n onSortChange?: (sort: DataTableSortConfig, state: DataTableState) => void\n /** フィルター変更時 */\n onFilterChange?: (filters: Record<string, unknown>, state: DataTableState) => void\n /** 行選択時 */\n onSelectionChange?: (selectedIds: Set<string | number>, state: DataTableState) => void\n /** 行アクション実行時 */\n onRowAction?: (actionId: string, row: DataTableRow, state: DataTableState) => void\n /** ページ変更時 */\n onPageChange?: (page: number, state: DataTableState) => void\n /** ページサイズ変更時 */\n onPageSizeChange?: (pageSize: number, state: DataTableState) => void\n /** グループ展開/折りたたみ時 */\n onGroupToggle?: (groupName: string, isExpanded: boolean, state: DataTableState) => void\n /** 列リサイズ時 */\n onColumnResize?: (columnId: string, width: number, state: DataTableState) => void\n}\n\n// =============================================================================\n// Utility Functions\n// =============================================================================\n\n/**\n * HTML特殊文字をエスケープ\n */\nfunction escapeHtml(text: string): string {\n const div = document.createElement('div')\n div.textContent = text\n return div.innerHTML\n}\n\n/**\n * ユニークIDを生成\n */\nfunction generateId(prefix: string): string {\n return `${prefix}-${Math.random().toString(36).substring(2, 11)}`\n}\n\n/**\n * セルの値をフォーマット\n */\nfunction formatCellValue(\n value: unknown,\n column: DataTableColumn\n): string {\n if (value === undefined || value === null) {\n return '-'\n }\n\n switch (column.format) {\n case 'number':\n return Number(value).toLocaleString('ja-JP')\n\n case 'currency': {\n const locale = column.currency_format?.locale ?? 'ja-JP'\n const currency = column.currency_format?.currency ?? 'JPY'\n return new Intl.NumberFormat(locale, {\n style: 'currency',\n currency,\n }).format(Number(value))\n }\n\n case 'date': {\n const date = new Date(String(value))\n return isNaN(date.getTime()) ? String(value) : date.toLocaleDateString('ja-JP')\n }\n\n case 'datetime': {\n const datetime = new Date(String(value))\n return isNaN(datetime.getTime()) ? String(value) : datetime.toLocaleString('ja-JP')\n }\n\n case 'status': {\n const statusMap = column.status_map ?? {}\n const statusInfo = statusMap[String(value)]\n if (statusInfo) {\n return statusInfo.label\n }\n return String(value)\n }\n\n case 'text':\n default:\n return String(value)\n }\n}\n\n/**\n * ステータスバッジのクラスを取得\n */\nfunction getStatusBadgeClass(\n value: unknown,\n column: DataTableColumn\n): string {\n if (column.format !== 'status' || !column.status_map) {\n return ''\n }\n\n const statusInfo = column.status_map[String(value)]\n if (!statusInfo) {\n return 'status-badge status-default'\n }\n\n return `status-badge status-${statusInfo.color}`\n}\n\n/**\n * データをソート\n */\nfunction sortData(\n data: DataTableRow[],\n sort: DataTableSortConfig | null,\n columns: DataTableColumn[]\n): DataTableRow[] {\n if (!sort) {\n return [...data]\n }\n\n const column = columns.find(c => c.id === sort.column)\n if (!column) {\n return [...data]\n }\n\n const fieldKey = column.field ?? column.id\n return [...data].sort((a, b) => {\n const aValue = a[fieldKey]\n const bValue = b[fieldKey]\n\n if (aValue === bValue) return 0\n if (aValue === undefined || aValue === null) return 1\n if (bValue === undefined || bValue === null) return -1\n\n let comparison = 0\n if (typeof aValue === 'number' && typeof bValue === 'number') {\n comparison = aValue - bValue\n } else if (typeof aValue === 'string' && typeof bValue === 'string') {\n comparison = aValue.localeCompare(bValue, 'ja-JP')\n } else {\n comparison = String(aValue).localeCompare(String(bValue), 'ja-JP')\n }\n\n return sort.direction === 'asc' ? comparison : -comparison\n })\n}\n\n/**\n * データをフィルター\n */\nfunction filterData(\n data: DataTableRow[],\n filterValues: Record<string, unknown>,\n filterFields: DataTableFilterField[]\n): DataTableRow[] {\n return data.filter(row => {\n return filterFields.every(filter => {\n const filterValue = filterValues[filter.id]\n if (filterValue === undefined || filterValue === null || filterValue === '') {\n return true\n }\n\n const column = filter.column\n const rowValue = row[column]\n\n switch (filter.type) {\n case 'text':\n return String(rowValue ?? '')\n .toLowerCase()\n .includes(String(filterValue).toLowerCase())\n\n case 'select':\n return String(rowValue) === String(filterValue)\n\n case 'number_range': {\n const range = filterValue as { min?: number; max?: number }\n const numValue = Number(rowValue)\n if (range.min !== undefined && numValue < range.min) return false\n if (range.max !== undefined && numValue > range.max) return false\n return true\n }\n\n case 'date_range': {\n const range = filterValue as { start?: string; end?: string }\n const dateValue = new Date(String(rowValue))\n if (range.start && dateValue < new Date(range.start)) return false\n if (range.end && dateValue > new Date(range.end)) return false\n return true\n }\n\n default:\n return true\n }\n })\n })\n}\n\n/**\n * ページネーションを適用\n */\nfunction paginateData(\n data: DataTableRow[],\n currentPage: number,\n pageSize: number\n): DataTableRow[] {\n const start = currentPage * pageSize\n return data.slice(start, start + pageSize)\n}\n\n// =============================================================================\n// Renderer Functions\n// =============================================================================\n\n/**\n * フィルターUIをレンダリング\n */\nfunction renderFilterUI(\n config: DataTableField,\n state: DataTableState,\n tableId: string\n): string {\n if (!config.filters?.fields || config.filters.fields.length === 0) {\n return ''\n }\n\n const layout = config.filters.layout ?? 'inline'\n const fields = config.filters.fields\n\n const fieldsHtml = fields.map(filter => {\n const currentValue = state.filterValues[filter.id] ?? ''\n\n switch (filter.type) {\n case 'text':\n return `\n <div class=\"filter-field\">\n <label class=\"filter-label\" for=\"${tableId}-filter-${escapeHtml(filter.id)}\">${escapeHtml(filter.label)}</label>\n <input\n type=\"text\"\n id=\"${tableId}-filter-${escapeHtml(filter.id)}\"\n class=\"form-input filter-input\"\n data-filter-id=\"${escapeHtml(filter.id)}\"\n value=\"${escapeHtml(String(currentValue))}\"\n placeholder=\"${escapeHtml(filter.placeholder ?? '')}\"\n />\n </div>\n `\n\n case 'select': {\n const options = filter.options ?? []\n const optionsHtml = options.map((opt: SelectOption) => {\n const selected = String(currentValue) === String(opt.value) ? 'selected' : ''\n return `<option value=\"${escapeHtml(String(opt.value))}\" ${selected}>${escapeHtml(opt.label)}</option>`\n }).join('')\n\n return `\n <div class=\"filter-field\">\n <label class=\"filter-label\" for=\"${tableId}-filter-${escapeHtml(filter.id)}\">${escapeHtml(filter.label)}</label>\n <select\n id=\"${tableId}-filter-${escapeHtml(filter.id)}\"\n class=\"form-select filter-select\"\n data-filter-id=\"${escapeHtml(filter.id)}\"\n >\n <option value=\"\">すべて</option>\n ${optionsHtml}\n </select>\n </div>\n `\n }\n\n default:\n return ''\n }\n }).join('')\n\n return `\n <div class=\"data-table-filters layout-${layout}\">\n <div class=\"filter-fields\">\n ${fieldsHtml}\n </div>\n <div class=\"filter-actions\">\n <button type=\"button\" class=\"btn btn-primary filter-apply-btn\">検索</button>\n <button type=\"button\" class=\"btn btn-secondary filter-reset-btn\">クリア</button>\n </div>\n </div>\n `\n}\n\n/**\n * 固定ヘッダー設定を取得\n */\nfunction getFixedHeaderConfig(config: DataTableField): { enabled: boolean; offset: number } {\n if (typeof config.fixed_header === 'boolean') {\n return { enabled: config.fixed_header, offset: 0 }\n }\n if (config.fixed_header) {\n return {\n enabled: config.fixed_header.enabled !== false,\n offset: config.fixed_header.offset ?? 0,\n }\n }\n return { enabled: false, offset: 0 }\n}\n\n/**\n * カラムリサイズ設定を取得\n */\nfunction getResizeConfig(config: DataTableField): { enabled: boolean; minWidth: number; maxWidth: number } {\n if (typeof config.column_resize === 'boolean') {\n return { enabled: config.column_resize, minWidth: 50, maxWidth: 500 }\n }\n if (config.column_resize) {\n return {\n enabled: config.column_resize.enabled !== false,\n minWidth: config.column_resize.min_width ?? 50,\n maxWidth: config.column_resize.max_width ?? 500,\n }\n }\n return { enabled: false, minWidth: 50, maxWidth: 500 }\n}\n\n/**\n * テーブルヘッダーをレンダリング\n */\nfunction renderTableHeader(\n config: DataTableField,\n state: DataTableState\n): string {\n const columns = config.columns\n const fixedHeaderConfig = getFixedHeaderConfig(config)\n const resizeConfig = getResizeConfig(config)\n\n const headerCells = columns.map(column => {\n const sortable = column.sortable !== false\n const isSorted = state.sort?.column === column.id\n const sortDirection = isSorted ? state.sort?.direction : null\n const nextDirection = sortDirection === 'asc' ? 'desc' : 'asc'\n\n const sortIcon = isSorted\n ? sortDirection === 'asc'\n ? ' ↑'\n : ' ↓'\n : ''\n\n const sortableClass = sortable ? 'sortable' : ''\n const sortedClass = isSorted ? `sorted sorted-${sortDirection}` : ''\n const alignClass = column.align ? `align-${column.align}` : ''\n const fixedClass = column.fixed ? `fixed-${column.fixed}` : ''\n\n // カラム幅の計算(state優先、次にcolumn.width、最後にデフォルト)\n const stateWidth = state.columnWidths[column.id]\n let widthStyle = ''\n if (stateWidth) {\n widthStyle = `width: ${stateWidth}px; min-width: ${stateWidth}px;`\n } else if (column.width) {\n widthStyle = `width: ${column.width};`\n }\n\n // リサイズハンドル\n const isResizable = resizeConfig.enabled && (column.resizable !== false)\n const resizeHandle = isResizable\n ? `<span class=\"column-resize-handle\" data-column-id=\"${escapeHtml(column.id)}\"></span>`\n : ''\n\n // colspan/rowspan (整数のみ許可)\n const colspanAttr = column.colspan && Number.isInteger(column.colspan) && column.colspan > 0\n ? `colspan=\"${column.colspan}\"`\n : ''\n const rowspanAttr = column.rowspan && Number.isInteger(column.rowspan) && column.rowspan > 0\n ? `rowspan=\"${column.rowspan}\"`\n : ''\n\n return `\n <th\n class=\"data-table-th ${sortableClass} ${sortedClass} ${alignClass} ${fixedClass}\"\n data-column-id=\"${escapeHtml(column.id)}\"\n data-sort-direction=\"${nextDirection}\"\n style=\"${widthStyle}\"\n ${colspanAttr}\n ${rowspanAttr}\n >\n <span class=\"th-content\">\n ${escapeHtml(column.label)}${sortIcon}\n </span>\n ${resizeHandle}\n </th>\n `\n }).join('')\n\n // 選択カラム\n const selectionHeader = config.selection === 'multiple'\n ? `<th class=\"data-table-th selection-header\">\n <input type=\"checkbox\" class=\"select-all-checkbox\" ${state.selectedRowIds.size === state.data.length && state.data.length > 0 ? 'checked' : ''} />\n </th>`\n : config.selection === 'single'\n ? '<th class=\"data-table-th selection-header\"></th>'\n : ''\n\n // アクションカラム\n const actionsHeader = config.row_actions && config.row_actions.length > 0\n ? '<th class=\"data-table-th actions-header\">操作</th>'\n : ''\n\n // 固定ヘッダー用のスタイル\n const stickyStyle = fixedHeaderConfig.enabled\n ? `top: ${fixedHeaderConfig.offset}px;`\n : ''\n const stickyClass = fixedHeaderConfig.enabled ? 'sticky-header' : ''\n\n return `\n <thead class=\"data-table-thead ${stickyClass}\" style=\"${stickyStyle}\">\n <tr>\n ${selectionHeader}\n ${headerCells}\n ${actionsHeader}\n </tr>\n </thead>\n `\n}\n\n/**\n * 行をグループ化して取得\n */\nfunction groupRows(\n data: DataTableRow[],\n config: DataTableField\n): Map<string, DataTableRow[]> {\n const groups = new Map<string, DataTableRow[]>()\n const groupField = config.grouping?.field ?? '_group'\n\n for (const row of data) {\n const groupName = String(row[groupField] ?? '')\n if (!groups.has(groupName)) {\n groups.set(groupName, [])\n }\n groups.get(groupName)!.push(row)\n }\n\n return groups\n}\n\n/**\n * グループヘッダー行をレンダリング\n */\nfunction renderGroupHeader(\n groupName: string,\n rowCount: number,\n columnCount: number,\n config: DataTableField,\n isCollapsed: boolean\n): string {\n if (!groupName) return ''\n\n const collapsible = config.grouping?.collapsible !== false\n const toggleIcon = collapsible\n ? `<span class=\"group-toggle-icon\">${isCollapsed ? '▶' : '▼'}</span>`\n : ''\n const toggleClass = collapsible ? 'collapsible' : ''\n const collapsedClass = isCollapsed ? 'collapsed' : ''\n\n return `\n <tr class=\"data-table-group-header ${toggleClass} ${collapsedClass}\" data-group-name=\"${escapeHtml(groupName)}\">\n <td colspan=\"${columnCount}\" class=\"group-header-cell\">\n ${toggleIcon}\n <span class=\"group-name\">${escapeHtml(groupName)}</span>\n <span class=\"group-count\">(${rowCount}件)</span>\n </td>\n </tr>\n `\n}\n\n/**\n * セル結合を考慮してセルをレンダリング\n */\nfunction renderCellWithMerge(\n row: DataTableRow,\n column: DataTableColumn,\n _value: unknown,\n formattedValue: string,\n statusClass: string,\n alignClass: string\n): string | null {\n const cellMerge = row._cellMerge?.[column.id] as DataTableCellMerge | undefined\n\n // このセルが他のセルに結合されている場合はnullを返す\n if (cellMerge?.hidden) {\n return null\n }\n\n const colspanAttr = cellMerge?.colspan && Number.isInteger(cellMerge.colspan) && cellMerge.colspan > 0\n ? `colspan=\"${cellMerge.colspan}\"`\n : ''\n const rowspanAttr = cellMerge?.rowspan && Number.isInteger(cellMerge.rowspan) && cellMerge.rowspan > 0\n ? `rowspan=\"${cellMerge.rowspan}\"`\n : ''\n const fixedClass = column.fixed ? `fixed-${column.fixed}` : ''\n\n const cellContent = statusClass\n ? `<span class=\"${statusClass}\">${escapeHtml(formattedValue)}</span>`\n : escapeHtml(formattedValue)\n\n return `<td class=\"data-table-td ${alignClass} ${fixedClass}\" ${colspanAttr} ${rowspanAttr}>${cellContent}</td>`\n}\n\n/**\n * テーブルボディをレンダリング\n */\nfunction renderTableBody(\n config: DataTableField,\n state: DataTableState,\n tableId: string\n): string {\n const columns = config.columns\n const displayData = state.data\n\n if (displayData.length === 0) {\n return renderEmptyState(config, columns.length)\n }\n\n // 選択カラムとアクションカラムを考慮した総カラム数\n let totalColumns = columns.length\n if (config.selection && config.selection !== 'none') totalColumns++\n if (config.row_actions && config.row_actions.length > 0) totalColumns++\n\n // グループ化が有効な場合\n if (config.grouping?.enabled) {\n const groups = groupRows(displayData, config)\n const rowsHtml: string[] = []\n\n for (const [groupName, groupRows] of groups) {\n const isCollapsed = state.collapsedGroups.has(groupName)\n\n // グループヘッダー\n if (groupName) {\n rowsHtml.push(renderGroupHeader(groupName, groupRows.length, totalColumns, config, isCollapsed))\n }\n\n // グループの行(折りたたまれている場合は非表示)\n if (!isCollapsed || !groupName) {\n for (const row of groupRows) {\n rowsHtml.push(renderTableRow(row, displayData.indexOf(row), config, state, tableId, columns))\n }\n }\n }\n\n return `<tbody class=\"data-table-tbody\">${rowsHtml.join('')}</tbody>`\n }\n\n // 通常のレンダリング\n const rows = displayData.map((row, rowIndex) => {\n return renderTableRow(row, rowIndex, config, state, tableId, columns)\n }).join('')\n\n return `\n <tbody class=\"data-table-tbody\">\n ${rows}\n </tbody>\n `\n}\n\n/**\n * テーブル行をレンダリング\n */\nfunction renderTableRow(\n row: DataTableRow,\n rowIndex: number,\n config: DataTableField,\n state: DataTableState,\n tableId: string,\n columns: DataTableColumn[]\n): string {\n const rowId = row.id\n const isSelected = state.selectedRowIds.has(rowId)\n const selectedClass = isSelected ? 'selected' : ''\n\n const cells = columns.map(column => {\n const fieldKey = column.field ?? column.id\n const value = row[fieldKey]\n const formattedValue = formatCellValue(value, column)\n const statusClass = getStatusBadgeClass(value, column)\n const alignClass = column.align ? `align-${column.align}` : ''\n\n return renderCellWithMerge(row, column, value, formattedValue, statusClass, alignClass)\n }).filter(cell => cell !== null).join('')\n\n // 選択セル\n const selectionCell = config.selection === 'multiple'\n ? `<td class=\"data-table-td selection-cell\">\n <input type=\"checkbox\" class=\"row-checkbox\" data-row-id=\"${escapeHtml(String(rowId))}\" ${isSelected ? 'checked' : ''} />\n </td>`\n : config.selection === 'single'\n ? `<td class=\"data-table-td selection-cell\">\n <input type=\"radio\" name=\"${tableId}-selection\" class=\"row-radio\" data-row-id=\"${escapeHtml(String(rowId))}\" ${isSelected ? 'checked' : ''} />\n </td>`\n : ''\n\n // アクションセル\n const actionsCell = config.row_actions && config.row_actions.length > 0\n ? `<td class=\"data-table-td actions-cell\">\n ${renderRowActions(config.row_actions, row)}\n </td>`\n : ''\n\n return `\n <tr class=\"data-table-tr ${selectedClass}\" data-row-id=\"${escapeHtml(String(rowId))}\" data-row-index=\"${rowIndex}\">\n ${selectionCell}\n ${cells}\n ${actionsCell}\n </tr>\n `\n}\n\n/**\n * 行アクションをレンダリング\n */\nfunction renderRowActions(\n actions: DataTableRowAction[],\n row: DataTableRow\n): string {\n return actions.map(action => {\n const styleClass = action.style ? `btn-${action.style}` : 'btn-link'\n const iconHtml = action.icon ? `<span class=\"action-icon\">${escapeHtml(action.icon)}</span>` : ''\n\n return `\n <button\n type=\"button\"\n class=\"btn btn-sm ${styleClass} row-action-btn\"\n data-action-id=\"${escapeHtml(action.id)}\"\n data-row-id=\"${escapeHtml(String(row.id))}\"\n ${action.confirm ? `data-confirm-title=\"${escapeHtml(action.confirm.title)}\" data-confirm-message=\"${escapeHtml(action.confirm.message)}\"` : ''}\n >\n ${iconHtml}\n <span class=\"action-label\">${escapeHtml(action.label)}</span>\n </button>\n `\n }).join('')\n}\n\n/**\n * 空状態をレンダリング()\n */\nfunction renderEmptyState(\n config: DataTableField,\n columnCount: number\n): string {\n const emptyState = config.empty_state ?? {}\n const title = emptyState.title ?? 'データがありません'\n const description = emptyState.description ?? ''\n const icon = emptyState.icon ?? '📭'\n\n // 選択カラムとアクションカラムを考慮\n let totalColumns = columnCount\n if (config.selection && config.selection !== 'none') totalColumns++\n if (config.row_actions && config.row_actions.length > 0) totalColumns++\n\n // プライマリアクションボタン\n const actionHtml = emptyState.action\n ? `<button type=\"button\" class=\"btn btn-primary empty-state-action\" data-handler=\"${escapeHtml(emptyState.action.handler)}\">${escapeHtml(emptyState.action.label)}</button>`\n : ''\n\n return `\n <tbody class=\"data-table-tbody data-table-empty-tbody\">\n <tr class=\"empty-state-row\">\n <td colspan=\"${totalColumns}\" class=\"empty-state-cell\">\n <div class=\"empty-state\">\n <div class=\"empty-state-icon-wrapper\">\n <span class=\"empty-state-icon\">${escapeHtml(icon)}</span>\n </div>\n <div class=\"empty-state-content\">\n <h4 class=\"empty-state-title\">${escapeHtml(title)}</h4>\n ${description ? `<p class=\"empty-state-description\">${escapeHtml(description)}</p>` : ''}\n </div>\n ${actionHtml ? `<div class=\"empty-state-actions\">${actionHtml}</div>` : ''}\n </div>\n </td>\n </tr>\n </tbody>\n `\n}\n\n/**\n * ページネーションUIをレンダリング\n */\nfunction renderPaginationUI(\n config: DataTableField,\n state: DataTableState,\n tableId: string\n): string {\n if (!config.pagination?.enabled) {\n return ''\n }\n\n const totalPages = Math.ceil(state.totalCount / state.pageSize)\n const currentPage = state.currentPage\n const pageSizeOptions = config.pagination.page_size_options ?? [10, 25, 50, 100]\n\n const pageSizeSelect = `\n <select class=\"form-select page-size-select\" data-table-id=\"${tableId}\">\n ${pageSizeOptions.map(size =>\n `<option value=\"${size}\" ${size === state.pageSize ? 'selected' : ''}>${size}件</option>`\n ).join('')}\n </select>\n `\n\n const pageInfo = `\n <span class=\"page-info\">\n ${state.totalCount}件中 ${currentPage * state.pageSize + 1}-${Math.min((currentPage + 1) * state.pageSize, state.totalCount)}件を表示\n </span>\n `\n\n const prevDisabled = currentPage === 0 ? 'disabled' : ''\n const nextDisabled = currentPage >= totalPages - 1 ? 'disabled' : ''\n\n return `\n <div class=\"data-table-pagination\">\n <div class=\"pagination-left\">\n <label class=\"page-size-label\">表示件数:</label>\n ${pageSizeSelect}\n </div>\n <div class=\"pagination-center\">\n ${pageInfo}\n </div>\n <div class=\"pagination-right\">\n <button type=\"button\" class=\"btn btn-secondary btn-sm pagination-prev\" ${prevDisabled}>\n 前へ\n </button>\n <span class=\"page-numbers\">\n ${currentPage + 1} / ${totalPages}\n </span>\n <button type=\"button\" class=\"btn btn-secondary btn-sm pagination-next\" ${nextDisabled}>\n 次へ\n </button>\n </div>\n </div>\n `\n}\n\n/**\n * ローディング状態をレンダリング\n */\nfunction renderLoadingOverlay(): string {\n return `\n <div class=\"data-table-loading\">\n <div class=\"loading-spinner\"></div>\n <span class=\"loading-text\">読み込み中...</span>\n </div>\n `\n}\n\n// =============================================================================\n// Data Table Class\n// =============================================================================\n\n/**\n * データテーブルコンポーネント\n */\nexport class DataTable {\n private config: DataTableField\n private container: HTMLElement\n private callbacks: DataTableCallbacks\n private state: DataTableState\n private tableId: string\n private boundHandleClick: (e: Event) => void\n private boundHandleChange: (e: Event) => void\n private boundHandleKeypress: (e: Event) => void\n private boundHandleMouseDown: (e: Event) => void\n private boundHandleMouseMove: (e: Event) => void\n private boundHandleMouseUp: (e: Event) => void\n\n // リサイズ関連の状態\n private resizingColumnId: string | null = null\n private resizeStartX: number = 0\n private resizeStartWidth: number = 0\n\n constructor(\n config: DataTableField,\n container: HTMLElement,\n callbacks: DataTableCallbacks = {}\n ) {\n this.config = config\n this.container = container\n this.callbacks = callbacks\n this.tableId = generateId('data-table')\n\n // イベントハンドラーをバインド(クリーンアップ用)\n this.boundHandleClick = this.handleClick.bind(this)\n this.boundHandleChange = this.handleChange.bind(this)\n this.boundHandleKeypress = this.handleKeypress.bind(this)\n this.boundHandleMouseDown = this.handleMouseDown.bind(this)\n this.boundHandleMouseMove = this.handleMouseMove.bind(this)\n this.boundHandleMouseUp = this.handleMouseUp.bind(this)\n\n // 初期状態を設定\n const initialData = config.data ?? []\n const pageSize = config.pagination?.page_size ?? 10\n\n // グループ化の初期状態を計算\n const collapsedGroups = new Set<string>()\n if (config.grouping?.enabled && config.grouping.default_expanded === false) {\n // デフォルトで折りたたむ場合、全グループを折りたたむ\n const groupField = config.grouping.field ?? '_group'\n for (const row of initialData) {\n const groupName = String(row[groupField] ?? '')\n if (groupName) {\n collapsedGroups.add(groupName)\n }\n }\n }\n\n this.state = {\n data: initialData,\n originalData: initialData,\n sort: config.default_sort ?? null,\n filterValues: {},\n selectedRowIds: new Set(),\n currentPage: config.pagination?.current_page ?? 0,\n pageSize,\n totalCount: config.pagination?.total_count ?? initialData.length,\n isLoading: false,\n collapsedGroups,\n columnWidths: {},\n }\n\n // 初期変換を適用(ソート、ページネーション)\n if (this.state.sort || this.config.pagination?.enabled) {\n this.applyDataTransformations()\n }\n }\n\n /**\n * 現在の状態を取得\n */\n getState(): DataTableState {\n return { ...this.state }\n }\n\n /**\n * データを設定\n */\n setData(data: DataTableRow[], totalCount?: number): void {\n this.state = {\n ...this.state,\n originalData: data,\n totalCount: totalCount ?? data.length,\n currentPage: 0,\n selectedRowIds: new Set(),\n }\n this.applyDataTransformations()\n this.render()\n }\n\n /**\n * データ変換(フィルター、ソート、ページネーション)を適用\n */\n private applyDataTransformations(): void {\n let data = [...this.state.originalData]\n\n // フィルター適用\n if (this.config.filters?.fields) {\n data = filterData(data, this.state.filterValues, this.config.filters.fields)\n }\n\n // ソート適用\n data = sortData(data, this.state.sort, this.config.columns)\n\n // 総件数を更新\n const totalCount = data.length\n\n // ページネーション適用\n if (this.config.pagination?.enabled) {\n data = paginateData(data, this.state.currentPage, this.state.pageSize)\n }\n\n this.state = {\n ...this.state,\n data,\n totalCount,\n }\n }\n\n /**\n * ソートを設定\n */\n setSort(column: string, direction: 'asc' | 'desc'): void {\n this.state = {\n ...this.state,\n sort: { column, direction },\n currentPage: 0,\n }\n this.applyDataTransformations()\n this.render()\n this.callbacks.onSortChange?.(this.state.sort!, this.state)\n }\n\n /**\n * フィルター値を設定\n */\n setFilterValues(values: Record<string, unknown>): void {\n this.state = {\n ...this.state,\n filterValues: values,\n currentPage: 0,\n }\n this.applyDataTransformations()\n this.render()\n this.callbacks.onFilterChange?.(values, this.state)\n }\n\n /**\n * フィルターをリセット\n */\n resetFilters(): void {\n this.setFilterValues({})\n }\n\n /**\n * 行を選択\n */\n selectRow(rowId: string | number): void {\n const newSelected = new Set(this.state.selectedRowIds)\n\n if (this.config.selection === 'single') {\n newSelected.clear()\n newSelected.add(rowId)\n } else if (this.config.selection === 'multiple') {\n if (newSelected.has(rowId)) {\n newSelected.delete(rowId)\n } else {\n newSelected.add(rowId)\n }\n }\n\n this.state = {\n ...this.state,\n selectedRowIds: newSelected,\n }\n this.render()\n this.callbacks.onSelectionChange?.(newSelected, this.state)\n }\n\n /**\n * 全行を選択/解除\n */\n selectAll(selected: boolean): void {\n const newSelected = selected\n ? new Set(this.state.data.map(row => row.id))\n : new Set<string | number>()\n\n this.state = {\n ...this.state,\n selectedRowIds: newSelected,\n }\n this.render()\n this.callbacks.onSelectionChange?.(newSelected, this.state)\n }\n\n /**\n * 選択された行を取得\n */\n getSelectedRows(): DataTableRow[] {\n return this.state.originalData.filter(row =>\n this.state.selectedRowIds.has(row.id)\n )\n }\n\n /**\n * ページを変更\n */\n setPage(page: number): void {\n const totalPages = Math.ceil(this.state.totalCount / this.state.pageSize)\n const newPage = Math.max(0, Math.min(page, totalPages - 1))\n\n this.state = {\n ...this.state,\n currentPage: newPage,\n }\n this.applyDataTransformations()\n this.render()\n this.callbacks.onPageChange?.(newPage, this.state)\n }\n\n /**\n * ページサイズを変更\n */\n setPageSize(pageSize: number): void {\n this.state = {\n ...this.state,\n pageSize,\n currentPage: 0,\n }\n this.applyDataTransformations()\n this.render()\n this.callbacks.onPageSizeChange?.(pageSize, this.state)\n }\n\n /**\n * ローディング状態を設定\n */\n setLoading(isLoading: boolean): void {\n this.state = {\n ...this.state,\n isLoading,\n }\n this.render()\n }\n\n /**\n * コンポーネントをレンダリング\n */\n render(): void {\n const classes = ['mokkun-data-table']\n if (this.config.striped) classes.push('striped')\n if (this.config.hoverable !== false) classes.push('hoverable')\n if (this.config.bordered) classes.push('bordered')\n if (this.config.compact) classes.push('compact')\n if (this.config.responsive !== false) classes.push('responsive')\n\n // 固定ヘッダー\n const fixedHeaderConfig = getFixedHeaderConfig(this.config)\n if (fixedHeaderConfig.enabled) classes.push('fixed-header')\n\n // 列リサイズ\n const resizeConfig = getResizeConfig(this.config)\n if (resizeConfig.enabled) classes.push('resizable-columns')\n\n // グループ化\n if (this.config.grouping?.enabled) classes.push('grouped')\n\n // テーブルレイアウト\n if (this.config.layout === 'fixed') classes.push('layout-fixed')\n\n const heightStyle = this.config.height ? `max-height: ${this.config.height};` : ''\n\n const html = `\n <div class=\"${classes.join(' ')}\" data-table-id=\"${this.tableId}\">\n ${this.config.label ? `<div class=\"data-table-header\">\n <h3 class=\"data-table-title\">${escapeHtml(this.config.label)}</h3>\n ${this.config.description ? `<p class=\"data-table-description\">${escapeHtml(this.config.description)}</p>` : ''}\n </div>` : ''}\n ${renderFilterUI(this.config, this.state, this.tableId)}\n <div class=\"data-table-wrapper\" style=\"${heightStyle}\">\n ${this.state.isLoading ? renderLoadingOverlay() : ''}\n <table class=\"data-table\">\n ${renderTableHeader(this.config, this.state)}\n ${renderTableBody(this.config, this.state, this.tableId)}\n </table>\n </div>\n ${renderPaginationUI(this.config, this.state, this.tableId)}\n </div>\n `\n\n this.detachEventListeners()\n this.container.innerHTML = html\n this.attachEventListeners()\n }\n\n /**\n * イベントリスナーを削除(メモリリーク防止)\n */\n private detachEventListeners(): void {\n this.container.removeEventListener('click', this.boundHandleClick)\n this.container.removeEventListener('change', this.boundHandleChange)\n this.container.removeEventListener('keypress', this.boundHandleKeypress)\n this.container.removeEventListener('mousedown', this.boundHandleMouseDown)\n document.removeEventListener('mousemove', this.boundHandleMouseMove)\n document.removeEventListener('mouseup', this.boundHandleMouseUp)\n }\n\n /**\n * イベントリスナーをアタッチ(イベント委譲パターン)\n */\n private attachEventListeners(): void {\n this.container.addEventListener('click', this.boundHandleClick)\n this.container.addEventListener('change', this.boundHandleChange)\n this.container.addEventListener('keypress', this.boundHandleKeypress)\n this.container.addEventListener('mousedown', this.boundHandleMouseDown)\n // マウスムーブとマウスアップはドキュメントレベルでリッスン(ドラッグ中にコンテナ外に出ても追従)\n document.addEventListener('mousemove', this.boundHandleMouseMove)\n document.addEventListener('mouseup', this.boundHandleMouseUp)\n }\n\n /**\n * クリックイベントハンドラー(イベント委譲)\n */\n private handleClick(e: Event): void {\n const target = e.target as HTMLElement\n\n // グループヘッダーのクリック(折りたたみ/展開)\n const groupHeader = target.closest('.data-table-group-header.collapsible')\n if (groupHeader) {\n const groupName = groupHeader.getAttribute('data-group-name')\n if (groupName) {\n this.toggleGroup(groupName)\n }\n return\n }\n\n // ソートヘッダー(リサイズハンドルは除外)\n if (!target.classList.contains('column-resize-handle')) {\n const sortableHeader = target.closest('.data-table-th.sortable')\n if (sortableHeader) {\n const columnId = sortableHeader.getAttribute('data-column-id')\n const direction = sortableHeader.getAttribute('data-sort-direction') as 'asc' | 'desc'\n if (columnId) {\n this.setSort(columnId, direction)\n }\n return\n }\n }\n\n // 行アクションボタン\n const actionBtn = target.closest('.row-action-btn')\n if (actionBtn) {\n const actionId = actionBtn.getAttribute('data-action-id')\n const rowId = actionBtn.getAttribute('data-row-id')\n const confirmTitle = actionBtn.getAttribute('data-confirm-title')\n\n if (actionId && rowId) {\n const row = this.state.originalData.find(r => String(r.id) === rowId)\n if (row) {\n if (confirmTitle) {\n const confirmMessage = actionBtn.getAttribute('data-confirm-message') ?? ''\n if (window.confirm(`${confirmTitle}\\n\\n${confirmMessage}`)) {\n this.callbacks.onRowAction?.(actionId, row, this.state)\n }\n } else {\n this.callbacks.onRowAction?.(actionId, row, this.state)\n }\n }\n }\n return\n }\n\n // フィルター適用ボタン\n if (target.closest('.filter-apply-btn')) {\n this.applyFiltersFromInputs()\n return\n }\n\n // フィルターリセットボタン\n if (target.closest('.filter-reset-btn')) {\n this.resetFilters()\n return\n }\n\n // 前ページボタン\n if (target.closest('.pagination-prev')) {\n this.setPage(this.state.currentPage - 1)\n return\n }\n\n // 次ページボタン\n if (target.closest('.pagination-next')) {\n this.setPage(this.state.currentPage + 1)\n return\n }\n }\n\n /**\n * 変更イベントハンドラー(イベント委譲)\n */\n private handleChange(e: Event): void {\n const target = e.target as HTMLElement\n\n // 行選択(チェックボックス)\n if (target.classList.contains('row-checkbox')) {\n const rowId = target.getAttribute('data-row-id')\n if (rowId) {\n this.selectRow(rowId)\n }\n return\n }\n\n // 行選択(ラジオボタン)\n if (target.classList.contains('row-radio')) {\n const rowId = target.getAttribute('data-row-id')\n if (rowId) {\n this.selectRow(rowId)\n }\n return\n }\n\n // 全選択チェックボックス\n if (target.classList.contains('select-all-checkbox')) {\n this.selectAll((target as HTMLInputElement).checked)\n return\n }\n\n // ページサイズ変更\n if (target.classList.contains('page-size-select')) {\n const pageSize = parseInt((target as HTMLSelectElement).value, 10)\n this.setPageSize(pageSize)\n return\n }\n }\n\n /**\n * キープレスイベントハンドラー(イベント委譲)\n */\n private handleKeypress(e: Event): void {\n const target = e.target as HTMLElement\n const keyEvent = e as KeyboardEvent\n\n // フィルター入力でEnterキー\n if (target.classList.contains('filter-input') && keyEvent.key === 'Enter') {\n this.applyFiltersFromInputs()\n return\n }\n }\n\n /**\n * グループを展開/折りたたみ\n */\n toggleGroup(groupName: string): void {\n const newCollapsed = new Set(this.state.collapsedGroups)\n const isCurrentlyCollapsed = newCollapsed.has(groupName)\n\n if (isCurrentlyCollapsed) {\n newCollapsed.delete(groupName)\n } else {\n newCollapsed.add(groupName)\n }\n\n this.state = {\n ...this.state,\n collapsedGroups: newCollapsed,\n }\n this.render()\n this.callbacks.onGroupToggle?.(groupName, isCurrentlyCollapsed, this.state)\n }\n\n /**\n * 全グループを展開\n */\n expandAllGroups(): void {\n this.state = {\n ...this.state,\n collapsedGroups: new Set(),\n }\n this.render()\n }\n\n /**\n * 全グループを折りたたむ\n */\n collapseAllGroups(): void {\n const groupField = this.config.grouping?.field ?? '_group'\n const allGroups = new Set<string>()\n\n for (const row of this.state.originalData) {\n const groupName = String(row[groupField] ?? '')\n if (groupName) {\n allGroups.add(groupName)\n }\n }\n\n this.state = {\n ...this.state,\n collapsedGroups: allGroups,\n }\n this.render()\n }\n\n /**\n * カラム幅を設定\n */\n setColumnWidth(columnId: string, width: number): void {\n // 入力の検証\n if (!Number.isFinite(width) || width < 0) {\n return\n }\n\n const resizeConfig = getResizeConfig(this.config)\n const clampedWidth = Math.max(\n resizeConfig.minWidth,\n Math.min(resizeConfig.maxWidth, width)\n )\n\n this.state = {\n ...this.state,\n columnWidths: {\n ...this.state.columnWidths,\n [columnId]: clampedWidth,\n },\n }\n this.render()\n this.callbacks.onColumnResize?.(columnId, clampedWidth, this.state)\n }\n\n /**\n * マウスダウンイベントハンドラー(リサイズ開始)\n */\n private handleMouseDown(e: Event): void {\n const target = e.target as HTMLElement\n\n // リサイズハンドル\n if (target.classList.contains('column-resize-handle')) {\n e.preventDefault()\n const columnId = target.getAttribute('data-column-id')\n if (columnId) {\n this.resizingColumnId = columnId\n\n const mouseEvent = e as MouseEvent\n this.resizeStartX = mouseEvent.clientX\n\n // 現在のカラム幅を取得\n const th = target.closest('.data-table-th') as HTMLElement\n if (th) {\n this.resizeStartWidth = th.offsetWidth\n }\n\n // リサイズ中のクラスを追加\n this.container.classList.add('resizing')\n }\n }\n }\n\n /**\n * マウスムーブイベントハンドラー(リサイズ中)\n */\n private handleMouseMove(e: Event): void {\n if (!this.resizingColumnId) return\n\n const mouseEvent = e as MouseEvent\n const delta = mouseEvent.clientX - this.resizeStartX\n const newWidth = this.resizeStartWidth + delta\n\n // リアルタイムでカラム幅を更新(パフォーマンスのためDOMを直接操作)\n const th = this.container.querySelector(\n `.data-table-th[data-column-id=\"${this.resizingColumnId}\"]`\n ) as HTMLElement\n if (th) {\n const resizeConfig = getResizeConfig(this.config)\n const clampedWidth = Math.max(\n resizeConfig.minWidth,\n Math.min(resizeConfig.maxWidth, newWidth)\n )\n th.style.width = `${clampedWidth}px`\n th.style.minWidth = `${clampedWidth}px`\n }\n }\n\n /**\n * マウスアップイベントハンドラー(リサイズ終了)\n */\n private handleMouseUp(_e: Event): void {\n if (!this.resizingColumnId) return\n\n // リサイズ中のクラスを削除\n this.container.classList.remove('resizing')\n\n // 最終的な幅を取得してstateに保存\n const th = this.container.querySelector(\n `.data-table-th[data-column-id=\"${this.resizingColumnId}\"]`\n ) as HTMLElement\n if (th) {\n const finalWidth = th.offsetWidth\n this.state = {\n ...this.state,\n columnWidths: {\n ...this.state.columnWidths,\n [this.resizingColumnId]: finalWidth,\n },\n }\n this.callbacks.onColumnResize?.(this.resizingColumnId, finalWidth, this.state)\n }\n\n this.resizingColumnId = null\n }\n\n /**\n * コンポーネントを破棄(クリーンアップ)\n */\n destroy(): void {\n this.detachEventListeners()\n this.container.innerHTML = ''\n }\n\n /**\n * 入力からフィルター値を適用\n */\n private applyFiltersFromInputs(): void {\n const filterValues: Record<string, unknown> = {}\n\n this.container.querySelectorAll('[data-filter-id]').forEach(element => {\n const filterId = element.getAttribute('data-filter-id')\n if (filterId) {\n const value = (element as HTMLInputElement | HTMLSelectElement).value\n if (value) {\n filterValues[filterId] = value\n }\n }\n })\n\n this.setFilterValues(filterValues)\n }\n}\n\n// =============================================================================\n// Static Renderer for form-fields.ts integration\n// =============================================================================\n\n/**\n * データテーブルフィールドを静的HTMLとしてレンダリング\n * form-fields.ts から呼び出される\n */\nexport function renderDataTableField(field: DataTableField): string {\n const classes = ['mokkun-data-table']\n if (field.striped) classes.push('striped')\n if (field.hoverable !== false) classes.push('hoverable')\n if (field.bordered) classes.push('bordered')\n if (field.compact) classes.push('compact')\n if (field.responsive !== false) classes.push('responsive')\n\n // 新機能のクラス\n const fixedHeaderConfig = getFixedHeaderConfig(field)\n if (fixedHeaderConfig.enabled) classes.push('fixed-header')\n\n const resizeConfig = getResizeConfig(field)\n if (resizeConfig.enabled) classes.push('resizable-columns')\n\n if (field.grouping?.enabled) classes.push('grouped')\n if (field.layout === 'fixed') classes.push('layout-fixed')\n\n const tableId = generateId('data-table')\n\n // データが空の場合はダミーデータを生成\n let data = field.data ?? []\n if (data.length === 0 && field.columns.length > 0) {\n const dummyRowCount = field.pagination?.page_size ?? 10\n data = generateDataTableDummyData(field.columns, dummyRowCount) as DataTableRow[]\n }\n\n const heightStyle = field.height ? `max-height: ${field.height};` : ''\n\n // 簡易的な静的レンダリング(ソート・フィルターはJSで動的に)\n const headerCells = field.columns.map(column => {\n const sortable = column.sortable !== false ? 'sortable' : ''\n const alignClass = column.align ? `align-${column.align}` : ''\n const fixedClass = column.fixed ? `fixed-${column.fixed}` : ''\n const widthStyle = column.width ? `width: ${column.width};` : ''\n\n // リサイズハンドル\n const isResizable = resizeConfig.enabled && (column.resizable !== false)\n const resizeHandle = isResizable\n ? `<span class=\"column-resize-handle\" data-column-id=\"${escapeHtml(column.id)}\"></span>`\n : ''\n\n // colspan/rowspan (整数のみ許可)\n const colspanAttr = column.colspan && Number.isInteger(column.colspan) && column.colspan > 0\n ? `colspan=\"${column.colspan}\"`\n : ''\n const rowspanAttr = column.rowspan && Number.isInteger(column.rowspan) && column.rowspan > 0\n ? `rowspan=\"${column.rowspan}\"`\n : ''\n\n return `\n <th class=\"data-table-th ${sortable} ${alignClass} ${fixedClass}\" data-column-id=\"${escapeHtml(column.id)}\" style=\"${widthStyle}\" ${colspanAttr} ${rowspanAttr}>\n <span class=\"th-content\">${escapeHtml(column.label)}</span>\n ${resizeHandle}\n </th>\n `\n }).join('')\n\n // 選択ヘッダー\n const selectionHeader = field.selection === 'multiple'\n ? '<th class=\"data-table-th selection-header\"><input type=\"checkbox\" class=\"select-all-checkbox\" /></th>'\n : field.selection === 'single'\n ? '<th class=\"data-table-th selection-header\"></th>'\n : ''\n\n // アクションヘッダー\n const actionsHeader = field.row_actions && field.row_actions.length > 0\n ? '<th class=\"data-table-th actions-header\">操作</th>'\n : ''\n\n // 行のレンダリング\n let bodyContent: string\n if (data.length === 0) {\n const emptyState = field.empty_state ?? {}\n const title = emptyState.title ?? 'データがありません'\n const description = emptyState.description ?? ''\n const icon = emptyState.icon ?? '📭'\n\n let totalColumns = field.columns.length\n if (field.selection && field.selection !== 'none') totalColumns++\n if (field.row_actions && field.row_actions.length > 0) totalColumns++\n\n // プライマリアクションボタン\n const actionHtml = emptyState.action\n ? `<button type=\"button\" class=\"btn btn-primary empty-state-action\" data-handler=\"${escapeHtml(emptyState.action.handler)}\">${escapeHtml(emptyState.action.label)}</button>`\n : ''\n\n bodyContent = `\n <tr class=\"empty-state-row\">\n <td colspan=\"${totalColumns}\" class=\"empty-state-cell\">\n <div class=\"empty-state\">\n <div class=\"empty-state-icon-wrapper\">\n <span class=\"empty-state-icon\">${escapeHtml(icon)}</span>\n </div>\n <div class=\"empty-state-content\">\n <h4 class=\"empty-state-title\">${escapeHtml(title)}</h4>\n ${description ? `<p class=\"empty-state-description\">${escapeHtml(description)}</p>` : ''}\n </div>\n ${actionHtml ? `<div class=\"empty-state-actions\">${actionHtml}</div>` : ''}\n </div>\n </td>\n </tr>\n `\n } else {\n bodyContent = data.map(row => {\n const cells = field.columns.map(column => {\n const fieldKey = column.field ?? column.id\n const value = row[fieldKey]\n const formattedValue = formatCellValue(value, column)\n const statusClass = getStatusBadgeClass(value, column)\n const alignClass = column.align ? `align-${column.align}` : ''\n const fixedClass = column.fixed ? `fixed-${column.fixed}` : ''\n\n // セル結合\n const cellMerge = row._cellMerge?.[column.id] as DataTableCellMerge | undefined\n if (cellMerge?.hidden) {\n return '' // 結合されて非表示のセルはスキップ\n }\n\n const colspanAttr = cellMerge?.colspan && Number.isInteger(cellMerge.colspan) && cellMerge.colspan > 0\n ? `colspan=\"${cellMerge.colspan}\"`\n : ''\n const rowspanAttr = cellMerge?.rowspan && Number.isInteger(cellMerge.rowspan) && cellMerge.rowspan > 0\n ? `rowspan=\"${cellMerge.rowspan}\"`\n : ''\n\n const cellContent = statusClass\n ? `<span class=\"${statusClass}\">${escapeHtml(formattedValue)}</span>`\n : escapeHtml(formattedValue)\n\n return `<td class=\"data-table-td ${alignClass} ${fixedClass}\" ${colspanAttr} ${rowspanAttr}>${cellContent}</td>`\n }).join('')\n\n const selectionCell = field.selection === 'multiple'\n ? `<td class=\"data-table-td selection-cell\"><input type=\"checkbox\" class=\"row-checkbox\" data-row-id=\"${escapeHtml(String(row.id))}\" /></td>`\n : field.selection === 'single'\n ? `<td class=\"data-table-td selection-cell\"><input type=\"radio\" name=\"${tableId}-selection\" class=\"row-radio\" data-row-id=\"${escapeHtml(String(row.id))}\" /></td>`\n : ''\n\n const actionsCell = field.row_actions && field.row_actions.length > 0\n ? `<td class=\"data-table-td actions-cell\">${renderRowActions(field.row_actions, row)}</td>`\n : ''\n\n return `\n <tr class=\"data-table-tr\" data-row-id=\"${escapeHtml(String(row.id))}\">\n ${selectionCell}\n ${cells}\n ${actionsCell}\n </tr>\n `\n }).join('')\n }\n\n const requiredMark = field.required ? '<span class=\"required-mark\">*</span>' : ''\n const description = field.description\n ? `<p class=\"field-description\">${escapeHtml(field.description)}</p>`\n : ''\n\n // 固定ヘッダー用のクラスとスタイル\n const stickyStyle = fixedHeaderConfig.enabled\n ? `top: ${fixedHeaderConfig.offset}px;`\n : ''\n const theadClass = fixedHeaderConfig.enabled ? 'data-table-thead sticky-header' : 'data-table-thead'\n\n // 空状態のtbodyクラス\n const tbodyClass = data.length === 0 ? 'data-table-tbody data-table-empty-tbody' : 'data-table-tbody'\n\n return `\n <div class=\"form-field field-type-data_table\" data-field-id=\"${escapeHtml(field.id)}\">\n <label class=\"field-label\">${escapeHtml(field.label)}${requiredMark}</label>\n ${description}\n <div class=\"${classes.join(' ')}\" data-table-id=\"${tableId}\">\n <div class=\"data-table-wrapper\" style=\"${heightStyle}\">\n <table class=\"data-table\">\n <thead class=\"${theadClass}\" style=\"${stickyStyle}\">\n <tr>\n ${selectionHeader}\n ${headerCells}\n ${actionsHeader}\n </tr>\n </thead>\n <tbody class=\"${tbodyClass}\">\n ${bodyContent}\n </tbody>\n </table>\n </div>\n </div>\n </div>\n `\n}\n","/**\n * Photo Manager Renderer\n * 写真管理画面のHTML生成(静的レンダリング用)\n */\n\nimport type { PhotoManagerField } from '../../types/schema'\n\n/**\n * ユニークIDを生成\n */\nfunction generateId(prefix: string): string {\n return `${prefix}-${Date.now()}-${Math.random().toString(36).substring(2, 9)}`\n}\n\n/**\n * HTMLエスケープ\n */\nfunction escapeHtml(str: string): string {\n const div = document.createElement('div')\n div.textContent = str\n return div.innerHTML\n}\n\n/**\n * 写真管理フィールドをHTML文字列としてレンダリング\n */\nexport function renderPhotoManagerField(field: PhotoManagerField): string {\n const managerId = generateId('photo-manager')\n const photos = field.photos ?? []\n const maxPhotos = field.max_photos ?? 20\n const maxFileSize = field.max_file_size ?? 10\n const acceptedFormats = field.accepted_formats ?? ['JPG', 'PNG']\n const columns = field.columns ?? 4\n\n // アップロードエリアHTML\n const uploadAreaHtml = `\n <div class=\"photo-upload-area\" data-manager-id=\"${managerId}\">\n <div class=\"upload-icon\">📷</div>\n <div class=\"upload-text\">ここにファイルをドラッグ&ドロップ<br>または</div>\n <button type=\"button\" class=\"btn btn-primary photo-select-btn\">ファイルを選択</button>\n <input type=\"file\" class=\"photo-file-input\" accept=\"${acceptedFormats.map(f => `.${f.toLowerCase()}`).join(',')}\" multiple hidden />\n <div class=\"upload-note\">対応形式: ${acceptedFormats.join(', ')} / 最大${maxFileSize}MB/枚 / 最大${maxPhotos}枚まで</div>\n </div>\n `\n\n // 写真カウンターHTML\n const counterHtml = `\n <div class=\"photo-count\">\n 登録済み写真: <strong>${photos.length}枚</strong> / 上限${maxPhotos}枚\n </div>\n `\n\n // ドラッグヒントHTML\n const dragHintHtml = photos.length > 0 ? `\n <div class=\"photo-drag-hint\">\n 💡 写真をドラッグ&ドロップして表示順序を変更できます\n </div>\n ` : ''\n\n // 写真グリッドHTML\n const photosHtml = photos.length > 0 ? `\n <div class=\"photo-grid\" style=\"--photo-columns: ${columns}\" data-manager-id=\"${managerId}\">\n ${photos.map((photo, index) => {\n const isMain = photo.is_main ?? (index === 0)\n return `\n <div class=\"photo-item\" data-photo-id=\"${escapeHtml(photo.id)}\" data-index=\"${index}\" draggable=\"true\">\n <img src=\"${escapeHtml(photo.src)}\" alt=\"${escapeHtml(photo.alt ?? `写真${index + 1}`)}\" loading=\"lazy\" />\n ${isMain ? '<span class=\"photo-main-badge\">メイン</span>' : ''}\n <span class=\"photo-order-badge\">${index + 1}</span>\n <div class=\"photo-overlay\">\n <button type=\"button\" class=\"btn btn-primary btn-sm photo-set-main-btn\" ${isMain ? 'disabled' : ''}>メインに設定</button>\n <button type=\"button\" class=\"btn btn-danger btn-sm photo-delete-btn\">削除</button>\n </div>\n </div>\n `\n }).join('')}\n </div>\n ` : `\n <div class=\"photo-empty\">\n <p>写真が登録されていません</p>\n </div>\n `\n\n return `\n <div class=\"field-wrapper field-type-photo_manager\">\n ${field.label ? `<label class=\"field-label\">${escapeHtml(field.label)}</label>` : ''}\n ${field.description ? `<p class=\"field-description\">${escapeHtml(field.description)}</p>` : ''}\n <div\n class=\"photo-manager\"\n id=\"${managerId}\"\n data-config='${JSON.stringify({ maxPhotos, maxFileSize, acceptedFormats, columns })}'\n role=\"region\"\n aria-label=\"${field.label ?? '写真管理'}\"\n >\n ${uploadAreaHtml}\n ${counterHtml}\n ${dragHintHtml}\n ${photosHtml}\n </div>\n </div>\n `\n}\n","/**\n * Form Field Renderers (Facade)\n * 各フォームフィールドタイプのHTML生成\n *\n * このモジュールはファサードとして機能し、実際のレンダリングロジックは\n * 各コンポーネントの静的renderFieldメソッドに委譲されます。\n */\n\nimport type {\n InputField,\n TextField,\n NumberField,\n TextareaField,\n SelectField,\n MultiSelectField,\n ComboboxField,\n RadioGroupField,\n CheckboxGroupField,\n DatePickerField,\n TimePickerField,\n DurationPickerField,\n DurationInputField,\n FileUploadField,\n RepeaterField,\n DataTableField,\n GoogleMapEmbedField,\n PhotoManagerField,\n ImageUploaderField,\n HeadingField,\n} from '../../types/schema'\n\n// コンポーネントインポート\nimport { Input } from './input'\nimport { Textarea } from './textarea'\nimport { Select } from './select'\nimport { RadioButton } from './radio'\nimport { Checkbox } from './checkbox'\nimport { Combobox } from './combobox'\nimport { Heading } from './heading'\nimport { DurationPicker } from './duration-picker'\nimport { DurationInput } from './duration-input'\nimport { Pagination } from './pagination'\nimport { Toggle } from './toggle'\nimport { Badge } from './badge'\nimport { Browser } from './browser'\nimport { Calendar } from './calendar'\nimport { Tooltip } from './tooltip'\nimport { FloatArea } from './float-area'\nimport { Loader } from './loader'\nimport { NotificationBar } from './notification-bar'\nimport { ResponseMessage } from './response-message'\nimport { Timeline } from './timeline'\nimport { Chip } from './chip'\nimport { StatusLabel } from './status-label'\nimport { SegmentedControl } from './segmented-control'\nimport { Tabs } from './tabs'\nimport { LineClamp } from './line-clamp'\nimport { Disclosure } from './disclosure'\nimport { AccordionPanel } from './accordion-panel'\nimport { SectionNav } from './section-nav'\nimport { DefinitionList } from './definition-list'\nimport { Stepper } from './stepper'\nimport { InformationPanel } from './information-panel'\nimport { Dropdown } from './dropdown'\nimport { DeleteConfirmDialog } from './delete-confirm-dialog'\nimport { renderDataTableField } from './data-table'\nimport { renderPhotoManagerField } from './photo-manager-renderer'\n\n// ヘルパー関数のインポート(まだ移行していないrender関数用)\nimport {\n escapeHtml,\n createFieldWrapper,\n getCommonAttributes,\n formatFileSize,\n formatMimeType,\n} from '../utils/field-helpers'\n\n// =============================================================================\n// Delegated Field Renderers (コンポーネントへ委譲)\n// =============================================================================\n\n/**\n * text → <input type=\"text\">\n * @deprecated Use Input.renderField instead\n */\nexport function renderTextField(field: TextField): string {\n return Input.renderField(field)\n}\n\n/**\n * number → <input type=\"number\">\n * @deprecated Use Input.renderField instead\n */\nexport function renderNumberField(field: NumberField): string {\n return Input.renderField(field)\n}\n\n/**\n * textarea → <textarea>\n * @deprecated Use Textarea.renderField instead\n */\nexport function renderTextareaField(field: TextareaField): string {\n return Textarea.renderField(field)\n}\n\n/**\n * select → <select>\n * @deprecated Use Select.renderField instead\n */\nexport function renderSelectField(field: SelectField): string {\n return Select.renderField(field)\n}\n\n/**\n * multi_select → <select multiple>\n * @deprecated Use Select.renderField instead\n */\nexport function renderMultiSelectField(field: MultiSelectField): string {\n return Select.renderField(field)\n}\n\n/**\n * combobox → Combobox component container\n * @deprecated Use Combobox.renderField instead\n */\nexport function renderComboboxField(field: ComboboxField): string {\n return Combobox.renderField(field)\n}\n\n/**\n * radio_group → <input type=\"radio\"> × N\n * @deprecated Use RadioButton.renderField instead\n */\nexport function renderRadioGroupField(field: RadioGroupField): string {\n return RadioButton.renderField(field)\n}\n\n/**\n * checkbox_group → <input type=\"checkbox\"> × N\n * @deprecated Use Checkbox.renderField instead\n */\nexport function renderCheckboxGroupField(field: CheckboxGroupField): string {\n return Checkbox.renderField(field)\n}\n\n/**\n * date_picker → <input type=\"date\">\n * @deprecated Use Input.renderField instead\n */\nexport function renderDatePickerField(field: DatePickerField): string {\n return Input.renderField(field)\n}\n\n/**\n * time_picker → <input type=\"time\">\n * @deprecated Use Input.renderField instead\n */\nexport function renderTimePickerField(field: TimePickerField): string {\n return Input.renderField(field)\n}\n\n/**\n * duration_picker → カスタム(時間:分 選択UI)\n * @deprecated Use DurationPicker.renderField instead\n */\nexport function renderDurationPickerField(field: DurationPickerField): string {\n return DurationPicker.renderField(field)\n}\n\n/**\n * duration_input → <input type=\"number\"> + 単位\n * @deprecated Use DurationInput.renderField instead\n */\nexport function renderDurationInputField(field: DurationInputField): string {\n return DurationInput.renderField(field)\n}\n\n/**\n * heading → 見出しフィールド\n * @deprecated Use Heading.renderField instead\n */\nexport function renderHeadingField(field: HeadingField): string {\n return Heading.renderField(field)\n}\n\n// =============================================================================\n// Local Field Renderers (まだコンポーネントに移行していないもの)\n// =============================================================================\n\n/**\n * file_upload → <input type=\"file\">\n */\nexport function renderFileUploadField(field: FileUploadField): string {\n const attrs: string[] = [getCommonAttributes(field)]\n\n if (field.accept && field.accept.length > 0) {\n attrs.push(`accept=\"${field.accept.join(',')}\"`)\n }\n if (field.multiple) {\n attrs.push('multiple')\n }\n\n const dropzoneClass = field.drag_drop ? 'with-dropzone' : ''\n\n let content = `<input type=\"file\" class=\"form-file\" ${attrs.join(' ')} />`\n\n if (field.drag_drop) {\n content = `\n <div class=\"file-dropzone ${dropzoneClass}\">\n ${content}\n <div class=\"dropzone-label\">\n ファイルをドラッグ&ドロップ または クリックして選択\n </div>\n </div>\n `\n }\n\n if (field.max_size) {\n const maxSizeMB = (field.max_size / (1024 * 1024)).toFixed(1)\n content += `<p class=\"file-size-hint\">最大ファイルサイズ: ${maxSizeMB} MB</p>`\n }\n\n return createFieldWrapper(field, content)\n}\n\n/**\n * google_map_embed → Google Maps 埋め込みコンポーネント\n */\nexport function renderGoogleMapEmbedFieldHtml(field: GoogleMapEmbedField): string {\n const height = field.height ?? '300'\n const width = field.width ?? '100%'\n const showOpenLink = field.show_open_link !== false\n\n const content = `\n <div class=\"google-map-embed-container\" data-field-id=\"${escapeHtml(field.id)}\">\n <div class=\"google-map-embed-input-wrapper\">\n <input\n type=\"text\"\n inputmode=\"url\"\n id=\"${escapeHtml(field.id)}\"\n name=\"${escapeHtml(field.id)}\"\n class=\"form-input google-map-embed-input\"\n placeholder=\"${escapeHtml(field.placeholder ?? 'Google Maps URL を入力してください')}\"\n maxlength=\"2048\"\n ${field.required ? 'required' : ''}\n ${field.disabled ? 'disabled' : ''}\n ${field.readonly ? 'readonly' : ''}\n />\n </div>\n <div class=\"google-map-embed-error\"></div>\n <div class=\"google-map-embed-preview\" data-height=\"${escapeHtml(height)}\" data-width=\"${escapeHtml(width)}\">\n <div class=\"google-map-embed-placeholder\">\n Google Maps URL を入力すると、ここにプレビューが表示されます\n </div>\n </div>\n ${showOpenLink ? `\n <div class=\"google-map-embed-link-container\">\n <a href=\"#\" class=\"google-map-embed-open-link disabled\" target=\"_blank\" rel=\"noopener noreferrer\" aria-disabled=\"true\">\n Googleマップで開く\n </a>\n </div>\n ` : ''}\n </div>\n `\n return createFieldWrapper(field, content)\n}\n\n/**\n * image_uploader → 画像アップローダーコンポーネント\n */\nexport function renderImageUploaderField(field: ImageUploaderField): string {\n const acceptedFormats = field.accepted_formats ?? ['image/jpeg', 'image/png', 'image/webp']\n const maxFileSize = field.max_file_size ?? 5 * 1024 * 1024 // 5MB\n const maxFiles = field.max_files ?? 10\n\n const formatsDisplay = acceptedFormats.map(formatMimeType).join(', ')\n const sizeDisplay = formatFileSize(maxFileSize)\n\n const content = `\n <div class=\"image-uploader-container\"\n data-field-id=\"${escapeHtml(field.id)}\"\n data-accepted-formats=\"${escapeHtml(acceptedFormats.join(','))}\"\n data-max-file-size=\"${maxFileSize}\"\n data-max-files=\"${maxFiles}\"\n data-min-files=\"${field.min_files ?? 0}\">\n <div class=\"uploader-wrapper\">\n <div class=\"upload-dropzone\">\n <input type=\"file\"\n class=\"file-input\"\n id=\"${escapeHtml(field.id)}-input\"\n accept=\"${acceptedFormats.join(',')}\"\n multiple\n ${field.disabled ? 'disabled' : ''} />\n <label class=\"dropzone-label\" for=\"${escapeHtml(field.id)}-input\">\n <div class=\"dropzone-icon\">\n <svg viewBox=\"0 0 24 24\" width=\"48\" height=\"48\">\n <path fill=\"currentColor\" d=\"M19.35 10.04A7.49 7.49 0 0012 4C9.11 4 6.6 5.64 5.35 8.04A5.994 5.994 0 000 14c0 3.31 2.69 6 6 6h13c2.76 0 5-2.24 5-5 0-2.64-2.05-4.78-4.65-4.96zM14 13v4h-4v-4H7l5-5 5 5h-3z\"/>\n </svg>\n </div>\n <span class=\"dropzone-text\">クリックまたはドラッグ&ドロップで画像を追加</span>\n </label>\n </div>\n <div class=\"uploader-hints\">\n <span class=\"hint-formats\">対応形式: ${formatsDisplay}</span>\n <span class=\"hint-size\">最大サイズ: ${sizeDisplay}/枚</span>\n <span class=\"hint-count\">最大${maxFiles}枚</span>\n </div>\n <div class=\"image-grid\"></div>\n </div>\n </div>\n `\n return createFieldWrapper(field, content)\n}\n\n/**\n * repeater → 静的なリピーターフィールド表示\n */\nexport function renderRepeaterFieldStatic(field: RepeaterField): string {\n const itemFields = field.item_fields ?? []\n const maxItems = field.max_items\n const addLabel = escapeHtml(field.add_button_label ?? 'Add Item')\n\n // item_fields の各フィールドをレンダリング\n const itemFieldsHtml = itemFields.map(f => renderField(f)).join('')\n\n const counterText = maxItems\n ? `1 / ${maxItems}`\n : '1 items'\n\n const sortableClass = field.sortable ? 'sortable' : ''\n\n const content = `\n <div class=\"mokkun-repeater ${sortableClass}\">\n <div class=\"repeater-wrapper\">\n <div class=\"repeater-header\">\n <span class=\"repeater-counter\">${escapeHtml(counterText)}</span>\n </div>\n <div class=\"repeater-items\">\n <div class=\"repeater-item expanded\">\n <div class=\"repeater-item-header\">\n ${field.sortable ? '<div class=\"repeater-item-handle\"></div>' : ''}\n <span class=\"repeater-item-number\">#1</span>\n <div class=\"repeater-item-spacer\"></div>\n </div>\n <div class=\"repeater-item-content\">\n ${itemFieldsHtml}\n </div>\n </div>\n </div>\n <div class=\"repeater-footer\">\n <button type=\"button\" class=\"repeater-add-btn\">${addLabel}</button>\n </div>\n </div>\n </div>\n `\n return createFieldWrapper(field, content)\n}\n\n// =============================================================================\n// Main Render Function\n// =============================================================================\n\n/**\n * フィールドタイプに応じてレンダリング\n */\nexport function renderField(field: InputField): string {\n switch (field.type) {\n case 'text':\n case 'number':\n case 'date_picker':\n case 'time_picker':\n return Input.renderField(field)\n case 'textarea':\n return Textarea.renderField(field)\n case 'select':\n case 'multi_select':\n return Select.renderField(field)\n case 'combobox':\n return Combobox.renderField(field)\n case 'radio_group':\n return RadioButton.renderField(field)\n case 'checkbox':\n case 'checkbox_group':\n return Checkbox.renderField(field)\n case 'duration_picker':\n return DurationPicker.renderField(field)\n case 'duration_input':\n return DurationInput.renderField(field)\n case 'file_upload':\n return renderFileUploadField(field)\n case 'image_uploader':\n return renderImageUploaderField(field)\n case 'repeater':\n return renderRepeaterFieldStatic(field as RepeaterField)\n case 'data_table':\n return renderDataTableField(field as DataTableField)\n case 'google_map_embed':\n return renderGoogleMapEmbedFieldHtml(field)\n case 'photo_manager':\n return renderPhotoManagerField(field as PhotoManagerField)\n case 'heading':\n return Heading.renderField(field)\n case 'pagination':\n return Pagination.renderField(field)\n case 'toggle':\n return Toggle.renderField(field)\n case 'badge':\n return Badge.renderField(field)\n case 'browser':\n return Browser.renderField(field)\n case 'calendar':\n return Calendar.renderField(field)\n case 'tooltip':\n return Tooltip.renderField(field)\n case 'float_area':\n return FloatArea.renderField(field)\n case 'loader':\n return Loader.renderField(field)\n case 'notification_bar':\n return NotificationBar.renderField(field)\n case 'response_message':\n return ResponseMessage.renderField(field)\n case 'timeline':\n return Timeline.renderField(field)\n case 'chip':\n return Chip.renderField(field)\n case 'status_label':\n return StatusLabel.renderField(field)\n case 'segmented_control':\n return SegmentedControl.renderField(field)\n case 'tabs':\n return Tabs.renderField(field)\n case 'line_clamp':\n return LineClamp.renderField(field)\n case 'disclosure':\n return Disclosure.renderField(field)\n case 'accordion_panel':\n return AccordionPanel.renderField(field)\n case 'section_nav':\n return SectionNav.renderField(field)\n case 'definition_list':\n return DefinitionList.renderField(field)\n case 'stepper':\n return Stepper.renderField(field)\n case 'information_panel':\n return InformationPanel.renderField(field)\n case 'dropdown':\n return Dropdown.renderField(field)\n case 'delete_confirm_dialog':\n return DeleteConfirmDialog.renderField(field)\n default:\n return createFieldWrapper(field, `<div class=\"unknown-field\">不明なフィールドタイプ: ${(field as InputField).type}</div>`)\n }\n}\n\n/**\n * 複数のフィールドをレンダリング\n */\nexport function renderFields(fields: InputField[]): string {\n return fields.map(renderField).join('')\n}\n","/**\n * Layout Component Renderers\n * レイアウト要素(display_fields, actions, filters)のHTML生成\n */\n\nimport type { Action, InputField } from '../../types/schema'\nimport { renderFields } from './form-fields'\n\n/**\n * HTML特殊文字をエスケープ\n */\nfunction escapeHtml(text: string): string {\n const div = document.createElement('div')\n div.textContent = text\n return div.innerHTML\n}\n\n// =============================================================================\n// Display Fields\n// =============================================================================\n\n/**\n * 表示フィールド(読み取り専用の値表示)\n */\nexport interface DisplayField {\n id: string\n label: string\n value?: string | number | boolean\n format?: 'text' | 'date' | 'number' | 'currency' | 'html'\n class?: string\n}\n\n/**\n * 表示フィールドをレンダリング\n */\nexport function renderDisplayField(field: DisplayField): string {\n const valueStr = field.value !== undefined ? String(field.value) : '-'\n const classes = ['display-field']\n if (field.class) {\n classes.push(field.class)\n }\n\n return `\n <div class=\"${classes.join(' ')}\" data-display-id=\"${escapeHtml(field.id)}\">\n <span class=\"display-label\">${escapeHtml(field.label)}</span>\n <span class=\"display-value\">${field.format === 'html' ? valueStr : escapeHtml(valueStr)}</span>\n </div>\n `\n}\n\n/**\n * 複数の表示フィールドをレンダリング\n */\nexport function renderDisplayFields(fields: DisplayField[]): string {\n if (fields.length === 0) {\n return ''\n }\n\n const fieldsHtml = fields.map(renderDisplayField).join('')\n return `<div class=\"display-fields\">${fieldsHtml}</div>`\n}\n\n// =============================================================================\n// Actions (Buttons)\n// =============================================================================\n\n/**\n * アクションボタンのスタイルをCSSクラスに変換\n */\nfunction getButtonClass(style?: Action['style']): string {\n const baseClass = 'btn'\n switch (style) {\n case 'primary':\n return `${baseClass} btn-primary`\n case 'secondary':\n return `${baseClass} btn-secondary`\n case 'danger':\n return `${baseClass} btn-danger`\n case 'link':\n return `${baseClass} btn-link`\n default:\n return `${baseClass} btn-secondary`\n }\n}\n\n/**\n * 単一アクション(ボタン)をレンダリング\n */\nexport function renderAction(action: Action): string {\n const buttonClass = getButtonClass(action.style)\n const iconHtml = action.icon ? `<span class=\"btn-icon\">${escapeHtml(action.icon)}</span>` : ''\n\n // data属性でアクション情報を埋め込む\n const dataAttrs: string[] = [\n `data-action-id=\"${escapeHtml(action.id)}\"`,\n `data-action-type=\"${escapeHtml(action.type)}\"`,\n ]\n\n if (action.type === 'navigate') {\n dataAttrs.push(`data-navigate-to=\"${escapeHtml(action.to)}\"`)\n }\n if (action.type === 'custom') {\n dataAttrs.push(`data-handler=\"${escapeHtml(action.handler)}\"`)\n }\n if (action.type === 'submit' && action.url) {\n dataAttrs.push(`data-url=\"${escapeHtml(action.url)}\"`)\n if (action.method) {\n dataAttrs.push(`data-method=\"${escapeHtml(action.method)}\"`)\n }\n }\n\n // 確認ダイアログ設定\n if (action.confirm) {\n dataAttrs.push(`data-confirm-title=\"${escapeHtml(action.confirm.title)}\"`)\n dataAttrs.push(`data-confirm-message=\"${escapeHtml(action.confirm.message)}\"`)\n }\n\n const buttonType = action.type === 'submit' ? 'submit' : action.type === 'reset' ? 'reset' : 'button'\n\n return `\n <button\n type=\"${buttonType}\"\n class=\"${buttonClass}\"\n ${dataAttrs.join(' ')}\n >\n ${iconHtml}\n <span class=\"btn-label\">${escapeHtml(action.label)}</span>\n </button>\n `\n}\n\n/**\n * アクション群をレンダリング\n */\nexport function renderActions(actions: Action[]): string {\n if (actions.length === 0) {\n return ''\n }\n\n const actionsHtml = actions.map(renderAction).join('')\n return `<div class=\"actions\">${actionsHtml}</div>`\n}\n\n// =============================================================================\n// Filters\n// =============================================================================\n\n/**\n * フィルター項目(検索・絞り込みUI)\n */\nexport interface FilterConfig {\n fields: InputField[]\n submitLabel?: string\n resetLabel?: string\n layout?: 'inline' | 'stacked'\n}\n\n/**\n * フィルターUIをレンダリング\n */\nexport function renderFilters(config: FilterConfig): string {\n const layout = config.layout ?? 'inline'\n const submitLabel = config.submitLabel ?? '検索'\n const resetLabel = config.resetLabel ?? 'クリア'\n\n const fieldsHtml = renderFields(config.fields)\n\n return `\n <div class=\"filters layout-${layout}\">\n <div class=\"filter-fields\">\n ${fieldsHtml}\n </div>\n <div class=\"filter-actions\">\n <button type=\"button\" class=\"btn btn-primary filter-submit\">${escapeHtml(submitLabel)}</button>\n <button type=\"button\" class=\"btn btn-secondary filter-reset\">${escapeHtml(resetLabel)}</button>\n </div>\n </div>\n `\n}\n\n// =============================================================================\n// Section Wrapper\n// =============================================================================\n\n/**\n * セクション(見出し付きコンテンツブロック)\n */\nexport interface SectionConfig {\n id?: string\n title?: string\n description?: string\n content: string\n collapsible?: boolean\n collapsed?: boolean\n}\n\n/**\n * セクションをレンダリング\n */\nexport function renderSection(config: SectionConfig): string {\n const classes = ['section']\n if (config.collapsible) {\n classes.push('collapsible')\n if (config.collapsed) {\n classes.push('collapsed')\n }\n }\n\n const idAttr = config.id ? `id=\"${escapeHtml(config.id)}\"` : ''\n const titleHtml = config.title\n ? `<h3 class=\"section-title\">${escapeHtml(config.title)}</h3>`\n : ''\n const descHtml = config.description\n ? `<p class=\"section-description\">${escapeHtml(config.description)}</p>`\n : ''\n\n return `\n <section class=\"${classes.join(' ')}\" ${idAttr}>\n ${titleHtml}\n ${descHtml}\n <div class=\"section-content\">\n ${config.content}\n </div>\n </section>\n `\n}\n\n// =============================================================================\n// Grid Layout\n// =============================================================================\n\n/**\n * グリッドレイアウト設定\n */\nexport interface GridConfig {\n columns?: number\n gap?: string\n items: string[]\n}\n\n/**\n * グリッドレイアウトをレンダリング\n */\nexport function renderGrid(config: GridConfig): string {\n const columns = config.columns ?? 2\n const gap = config.gap ?? '1rem'\n\n const style = `\n display: grid;\n grid-template-columns: repeat(${columns}, 1fr);\n gap: ${gap};\n `\n\n const itemsHtml = config.items\n .map(item => `<div class=\"grid-item\">${item}</div>`)\n .join('')\n\n return `<div class=\"grid-layout\" style=\"${style}\">${itemsHtml}</div>`\n}\n","/**\n * Screen Renderer\n * 画面全体のレンダリングを担当\n */\n\nimport type { ScreenDefinition, LayoutConfig, InputField } from '../types/schema'\nimport { renderFields } from './components/form-fields'\nimport { renderActions } from './components/layout'\nimport { SectionNav, type SectionDefinition } from './components/section-nav'\nimport { AppHeader, type AppHeaderConfig, type NavItem, type NavDropdownItem } from './components/app-header'\nimport { AppNavi, type AppNaviItem, type AppNaviButtonItem, type AppNaviAnchorItem, type AppNaviDropdownItem } from './components/app-navi'\n\n/**\n * HTML特殊文字をエスケープ\n */\nfunction escapeHtml(text: string): string {\n const div = document.createElement('div')\n div.textContent = text\n return div.innerHTML\n}\n\n/**\n * レイアウト設定からCSSスタイルを生成\n */\nfunction getLayoutStyle(layout?: LayoutConfig): string {\n if (!layout) {\n return ''\n }\n\n const styles: string[] = []\n\n if (layout.columns && layout.columns > 1) {\n styles.push(`display: grid`)\n styles.push(`grid-template-columns: repeat(${layout.columns}, 1fr)`)\n }\n\n if (layout.gap) {\n styles.push(`gap: ${layout.gap}`)\n }\n\n return styles.length > 0 ? `style=\"${styles.join('; ')}\"` : ''\n}\n\n/**\n * 画面ヘッダーをレンダリング\n */\nfunction renderScreenHeader(screen: ScreenDefinition): string {\n const descriptionHtml = screen.description\n ? `<p class=\"screen-description\">${escapeHtml(screen.description)}</p>`\n : ''\n\n return `\n <header class=\"screen-header\">\n <h1 class=\"screen-title\">${escapeHtml(screen.title)}</h1>\n ${descriptionHtml}\n </header>\n `\n}\n\n/**\n * フォームフィールドセクションをレンダリング\n */\nfunction renderFieldsSection(screen: ScreenDefinition): string {\n if (!screen.fields || screen.fields.length === 0) {\n return ''\n }\n\n const layoutStyle = getLayoutStyle(screen.layout)\n const fieldsHtml = renderFields(screen.fields)\n\n return `\n <div class=\"fields-section\" ${layoutStyle}>\n ${fieldsHtml}\n </div>\n `\n}\n\n/**\n * アクションセクションをレンダリング\n */\nfunction renderActionsSection(screen: ScreenDefinition): string {\n if (!screen.actions || screen.actions.length === 0) {\n return ''\n }\n\n return `\n <div class=\"actions-section\">\n ${renderActions(screen.actions)}\n </div>\n `\n}\n\n/**\n * ウィザードプログレスバーをレンダリング\n */\nfunction renderWizardProgress(\n screen: ScreenDefinition,\n currentStepIndex: number\n): string {\n if (!screen.wizard || !screen.wizard.show_progress) {\n return ''\n }\n\n const steps = screen.wizard.steps\n const stepsHtml = steps.map((step, index) => {\n const classes = ['wizard-progress-step']\n if (index < currentStepIndex) {\n classes.push('completed')\n } else if (index === currentStepIndex) {\n classes.push('current')\n }\n\n return `\n <div class=\"${classes.join(' ')}\" data-step-index=\"${index}\">\n <span class=\"step-number\">${index + 1}</span>\n <span class=\"step-title\">${escapeHtml(step.title)}</span>\n </div>\n `\n }).join('')\n\n return `\n <div class=\"wizard-progress\">\n ${stepsHtml}\n </div>\n `\n}\n\n/**\n * ウィザードステップをレンダリング\n */\nfunction renderWizardStep(\n screen: ScreenDefinition,\n stepIndex: number\n): string {\n if (!screen.wizard) {\n return ''\n }\n\n const step = screen.wizard.steps[stepIndex]\n if (!step) {\n return '<div class=\"error\">無効なステップです</div>'\n }\n\n const isFirstStep = stepIndex === 0\n const isLastStep = stepIndex === screen.wizard.steps.length - 1\n const allowBack = screen.wizard.allow_back ?? true\n\n const descriptionHtml = step.description\n ? `<p class=\"wizard-step-description\">${escapeHtml(step.description)}</p>`\n : ''\n\n const fieldsHtml = renderFields(step.fields)\n\n const backButton = !isFirstStep && allowBack\n ? `<button type=\"button\" class=\"btn btn-secondary wizard-back\" data-step=\"${stepIndex - 1}\">戻る</button>`\n : ''\n\n const nextButton = !isLastStep\n ? `<button type=\"button\" class=\"btn btn-primary wizard-next\" data-step=\"${stepIndex + 1}\">次へ</button>`\n : ''\n\n const submitButton = isLastStep\n ? `<button type=\"submit\" class=\"btn btn-primary wizard-submit\">送信</button>`\n : ''\n\n return `\n <div class=\"wizard-step\" data-step-id=\"${escapeHtml(step.id)}\" data-step-index=\"${stepIndex}\">\n <h2 class=\"wizard-step-title\">${escapeHtml(step.title)}</h2>\n ${descriptionHtml}\n <div class=\"wizard-step-fields\">\n ${fieldsHtml}\n </div>\n <div class=\"wizard-navigation\">\n ${backButton}\n ${nextButton}\n ${submitButton}\n </div>\n </div>\n `\n}\n\n/**\n * ウィザード画面をレンダリング\n */\nexport function renderWizardScreen(\n screen: ScreenDefinition,\n currentStepIndex: number = 0\n): string {\n if (!screen.wizard) {\n return renderScreen(screen)\n }\n\n const progressHtml = renderWizardProgress(screen, currentStepIndex)\n const stepHtml = renderWizardStep(screen, currentStepIndex)\n\n return `\n <div class=\"screen wizard-screen\">\n ${renderScreenHeader(screen)}\n ${progressHtml}\n <form class=\"wizard-form\" data-current-step=\"${currentStepIndex}\">\n ${stepHtml}\n </form>\n </div>\n `\n}\n\n/**\n * セクションIDを生成(セクション名から安全なIDを生成)\n */\nfunction generateSectionId(sectionName: string, index: number): string {\n const safeName = sectionName\n .toLowerCase()\n .replace(/[^a-z0-9\\u3040-\\u309f\\u30a0-\\u30ff\\u4e00-\\u9faf]/g, '_')\n .replace(/_+/g, '_')\n .replace(/^_|_$/g, '')\n return `section-${safeName || index}`\n}\n\n/**\n * セクション付き画面をレンダリング(SectionNav使用)\n */\nfunction renderSectionsScreen(screen: ScreenDefinition): string {\n if (!screen.sections || screen.sections.length === 0) {\n return renderScreen(screen)\n }\n\n const appLayoutHtml = renderAppLayoutContainers(screen)\n const headerHtml = renderScreenHeader(screen)\n const actionsHtml = renderActionsSection(screen)\n\n // セクションのHTMLを生成\n const sectionsHtml = screen.sections.map((section, index) => {\n const sectionId = generateSectionId(section.section_name, index)\n const fields = section.input_fields as InputField[] | undefined\n\n const fieldsHtml = fields && fields.length > 0\n ? renderFields(fields)\n : ''\n\n const publishToggleHtml = section.publish_toggle\n ? `<div class=\"section-publish-toggle\">\n <label class=\"checkbox-option\">\n <input type=\"checkbox\" name=\"${sectionId}_publish\" />\n <span>このセクションを公開する</span>\n </label>\n </div>`\n : ''\n\n return `\n <section id=\"${escapeHtml(sectionId)}\" class=\"form-section\">\n <h2 class=\"section-title\">\n ${section.icon ? `<span class=\"section-icon\">${escapeHtml(section.icon)}</span>` : ''}\n ${escapeHtml(section.section_name)}\n </h2>\n ${publishToggleHtml}\n <div class=\"section-fields\">\n ${fieldsHtml}\n </div>\n </section>\n `\n }).join('')\n\n return `\n <div class=\"screen screen-with-sections\">\n ${appLayoutHtml}\n ${headerHtml}\n <div id=\"section-nav-container\" class=\"section-nav-container\"></div>\n <form class=\"screen-form\">\n ${sectionsHtml}\n ${actionsHtml}\n </form>\n </div>\n `\n}\n\n/**\n * AppHeader/AppNaviのコンテナをレンダリング\n */\nfunction renderAppLayoutContainers(screen: ScreenDefinition): string {\n const appHeaderHtml = screen.app_header\n ? '<div id=\"app-header-container\" class=\"app-header-container\"></div>'\n : ''\n\n const appNaviHtml = screen.app_navi\n ? '<div id=\"app-navi-container\" class=\"app-navi-container\"></div>'\n : ''\n\n return appHeaderHtml + appNaviHtml\n}\n\n/**\n * 通常画面をレンダリング\n */\nexport function renderScreen(screen: ScreenDefinition): string {\n // ウィザード画面の場合は専用レンダラーを使用\n if (screen.wizard) {\n return renderWizardScreen(screen, 0)\n }\n\n // セクション付き画面の場合\n if (screen.sections && screen.sections.length > 0) {\n return renderSectionsScreen(screen)\n }\n\n const appLayoutHtml = renderAppLayoutContainers(screen)\n const headerHtml = renderScreenHeader(screen)\n const fieldsHtml = renderFieldsSection(screen)\n const actionsHtml = renderActionsSection(screen)\n\n return `\n <div class=\"screen\">\n ${appLayoutHtml}\n ${headerHtml}\n <form class=\"screen-form\">\n ${fieldsHtml}\n ${actionsHtml}\n </form>\n </div>\n `\n}\n\n/**\n * 画面コントローラーインターフェース\n */\nexport interface ScreenController {\n /** AppHeaderインスタンス(存在する場合) */\n appHeader?: AppHeader\n /** AppNaviインスタンス(存在する場合) */\n appNavi?: AppNavi\n /** SectionNavコントローラー(存在する場合) */\n sectionNav?: SectionNavController\n /** 全コンポーネントを破棄 */\n destroy: () => void\n}\n\n/**\n * 画面をDOMにマウント\n */\nexport function mountScreen(\n container: HTMLElement,\n screen: ScreenDefinition\n): ScreenController {\n container.innerHTML = renderScreen(screen)\n\n const controller: ScreenController = {\n destroy: () => {\n controller.appHeader?.destroy()\n controller.appNavi?.destroy()\n controller.sectionNav?.destroy()\n },\n }\n\n // AppHeaderの初期化\n if (screen.app_header) {\n const appHeaderContainer = container.querySelector<HTMLElement>('#app-header-container')\n if (appHeaderContainer) {\n controller.appHeader = initializeAppHeader(appHeaderContainer, screen)\n }\n }\n\n // AppNaviの初期化\n if (screen.app_navi) {\n const appNaviContainer = container.querySelector<HTMLElement>('#app-navi-container')\n if (appNaviContainer) {\n controller.appNavi = initializeAppNavi(appNaviContainer, screen)\n }\n }\n\n // セクション付き画面の場合はSectionNavを初期化\n if (screen.sections && screen.sections.length > 0) {\n controller.sectionNav = initializeSectionNav(container, screen) ?? undefined\n }\n\n return controller\n}\n\n/**\n * AppHeaderを初期化\n */\nfunction initializeAppHeader(\n container: HTMLElement,\n screen: ScreenDefinition\n): AppHeader | undefined {\n if (!screen.app_header) {\n return undefined\n }\n\n const config = screen.app_header\n\n // スキーマ型からコンポーネント設定に変換\n const appHeaderConfig: AppHeaderConfig = {\n logo: config.logo,\n logoAlt: config.logoAlt,\n logoHref: config.logoHref,\n appName: config.appName,\n tenants: config.tenants,\n currentTenantId: config.currentTenantId,\n userInfo: {\n name: config.userInfo.name,\n email: config.userInfo.email,\n avatarUrl: config.userInfo.avatarUrl,\n },\n navigations: config.navigations?.map((nav): NavItem => ({\n id: nav.id,\n label: nav.label,\n href: nav.href,\n active: nav.active,\n disabled: nav.disabled,\n dropdown: nav.dropdown?.map((item): NavDropdownItem => ({\n id: item.id,\n label: item.label,\n href: item.href,\n divider: item.divider,\n })),\n })),\n appLauncher: config.appLauncher,\n helpPageUrl: config.helpPageUrl,\n showReleaseNote: config.showReleaseNote,\n releaseNoteText: config.releaseNoteText,\n showDataSync: config.showDataSync,\n }\n\n const appHeader = new AppHeader(container, appHeaderConfig)\n appHeader.render()\n\n return appHeader\n}\n\n/**\n * AppNaviを初期化\n */\nfunction initializeAppNavi(\n container: HTMLElement,\n screen: ScreenDefinition\n): AppNavi | undefined {\n if (!screen.app_navi) {\n return undefined\n }\n\n const config = screen.app_navi\n\n // スキーマ型からコンポーネント設定に変換\n const items: AppNaviItem[] = config.items.map((item) => {\n switch (item.type) {\n case 'button':\n return {\n type: 'button',\n id: item.id,\n label: item.label,\n icon: item.icon,\n disabled: item.disabled,\n current: item.current,\n } as AppNaviButtonItem\n\n case 'anchor':\n return {\n type: 'anchor',\n id: item.id,\n label: item.label,\n icon: item.icon,\n disabled: item.disabled,\n current: item.current,\n href: item.href ?? '#',\n target: item.target,\n } as AppNaviAnchorItem\n\n case 'dropdown':\n return {\n type: 'dropdown',\n id: item.id,\n label: item.label,\n icon: item.icon,\n disabled: item.disabled,\n current: item.current,\n dropdownItems: item.dropdownItems?.map((dropdownItem) => ({\n id: dropdownItem.id,\n label: dropdownItem.label,\n icon: dropdownItem.icon,\n disabled: dropdownItem.disabled,\n href: dropdownItem.href,\n })) ?? [],\n } as AppNaviDropdownItem\n\n default:\n return {\n type: 'button',\n id: item.id,\n label: item.label,\n icon: item.icon,\n disabled: item.disabled,\n current: item.current,\n } as AppNaviButtonItem\n }\n })\n\n const appNavi = new AppNavi(container, {\n label: config.label,\n items,\n })\n appNavi.render()\n\n return appNavi\n}\n\n/**\n * セクションナビゲーションを初期化\n */\nexport function initializeSectionNav(\n container: HTMLElement,\n screen: ScreenDefinition\n): SectionNavController | null {\n if (!screen.sections || screen.sections.length === 0) {\n return null\n }\n\n const navContainer = container.querySelector<HTMLElement>('#section-nav-container')\n if (!navContainer) {\n return null\n }\n\n // セクション定義を生成\n const sections: SectionDefinition[] = screen.sections.map((section, index) => ({\n id: generateSectionId(section.section_name, index),\n label: section.section_name,\n icon: section.icon,\n }))\n\n const sectionNav = new SectionNav(\n {\n sections,\n scrollOffset: 120, // ヘッダー + ナビの高さ\n mobileMode: 'scroll',\n stickyTop: '60px', // ヘッダーの下に配置\n },\n navContainer\n )\n\n sectionNav.render()\n\n return {\n getActiveSection: () => sectionNav.getActiveSection(),\n scrollToSection: (sectionId: string) => sectionNav.scrollToSection(sectionId),\n destroy: () => sectionNav.destroy(),\n }\n}\n\n/**\n * セクションナビコントローラーインターフェース\n */\nexport interface SectionNavController {\n getActiveSection: () => SectionDefinition | undefined\n scrollToSection: (sectionId: string) => void\n destroy: () => void\n}\n\n/**\n * ウィザード画面をDOMにマウント(ステップ管理付き)\n */\nexport function mountWizardScreen(\n container: HTMLElement,\n screen: ScreenDefinition,\n initialStep: number = 0\n): WizardController {\n let currentStep = initialStep\n\n function render(): void {\n container.innerHTML = renderWizardScreen(screen, currentStep)\n attachWizardEventListeners()\n }\n\n function attachWizardEventListeners(): void {\n // 次へボタン\n container.querySelectorAll('.wizard-next').forEach(btn => {\n btn.addEventListener('click', () => {\n if (screen.wizard && currentStep < screen.wizard.steps.length - 1) {\n currentStep++\n render()\n }\n })\n })\n\n // 戻るボタン\n container.querySelectorAll('.wizard-back').forEach(btn => {\n btn.addEventListener('click', () => {\n if (currentStep > 0) {\n currentStep--\n render()\n }\n })\n })\n }\n\n render()\n\n return {\n getCurrentStep: () => currentStep,\n goToStep: (step: number) => {\n if (screen.wizard && step >= 0 && step < screen.wizard.steps.length) {\n currentStep = step\n render()\n }\n },\n nextStep: () => {\n if (screen.wizard && currentStep < screen.wizard.steps.length - 1) {\n currentStep++\n render()\n }\n },\n prevStep: () => {\n if (currentStep > 0) {\n currentStep--\n render()\n }\n },\n }\n}\n\n/**\n * ウィザードコントローラーインターフェース\n */\nexport interface WizardController {\n getCurrentStep: () => number\n goToStep: (step: number) => void\n nextStep: () => void\n prevStep: () => void\n}\n","/**\n * Action Handler\n * アクションボタンのイベント処理(確認ダイアログ統合)\n */\n\nimport {\n DeleteConfirmDialog,\n type DeleteConfirmDialogConfig,\n type DependencyInfo,\n} from './components/delete-confirm-dialog'\n\n// =============================================================================\n// Types\n// =============================================================================\n\n/**\n * アクションハンドラーのコールバック\n */\nexport interface ActionHandlerCallbacks {\n /** submit アクション実行時 */\n onSubmit?: (actionId: string, url?: string, method?: string) => void\n /** navigate アクション実行時 */\n onNavigate?: (actionId: string, to: string) => void\n /** custom アクション実行時 */\n onCustom?: (actionId: string, handler: string) => void\n /** reset アクション実行時 */\n onReset?: (actionId: string) => void\n /** アクションがキャンセルされた時 */\n onCancel?: (actionId: string) => void\n}\n\n/**\n * 削除確認ダイアログの拡張設定(YAMLから取得する追加情報)\n */\nexport interface DeleteConfirmExtendedConfig {\n /** 依存データを取得する関数 */\n getDependencies?: () => DependencyInfo[] | Promise<DependencyInfo[]>\n /** 削除対象名を取得する関数 */\n getTargetName?: () => string\n /** 削除対象タイプ */\n targetType?: string\n /** 警告メッセージ */\n warningMessage?: string\n}\n\n// =============================================================================\n// Action Handler Class\n// =============================================================================\n\n/**\n * アクションハンドラー\n * ボタンクリック時の処理と確認ダイアログの表示を管理\n */\nexport class ActionHandler {\n private container: HTMLElement\n private callbacks: ActionHandlerCallbacks\n private deleteConfirmConfigs: Map<string, DeleteConfirmExtendedConfig>\n private boundClickHandler: (e: Event) => void\n\n constructor(\n container: HTMLElement,\n callbacks: ActionHandlerCallbacks = {},\n deleteConfirmConfigs: Map<string, DeleteConfirmExtendedConfig> = new Map()\n ) {\n this.container = container\n this.callbacks = callbacks\n this.deleteConfirmConfigs = deleteConfirmConfigs\n this.boundClickHandler = this.handleClick.bind(this)\n }\n\n /**\n * イベントリスナーを設定\n */\n attach(): void {\n this.container.addEventListener('click', this.boundClickHandler)\n }\n\n /**\n * イベントリスナーを削除\n */\n detach(): void {\n this.container.removeEventListener('click', this.boundClickHandler)\n }\n\n /**\n * 削除確認の設定を登録\n */\n registerDeleteConfirmConfig(actionId: string, config: DeleteConfirmExtendedConfig): void {\n this.deleteConfirmConfigs.set(actionId, config)\n }\n\n /**\n * クリックイベントハンドラー\n */\n private handleClick(e: Event): void {\n const target = e.target as HTMLElement\n const button = target.closest('[data-action-id]') as HTMLElement | null\n\n if (!button) {\n return\n }\n\n const actionId = button.dataset.actionId\n const actionType = button.dataset.actionType\n\n if (!actionId || !actionType) {\n return\n }\n\n // 確認ダイアログが必要かチェック\n const confirmTitle = button.dataset.confirmTitle\n const confirmMessage = button.dataset.confirmMessage\n\n if (confirmTitle && confirmMessage) {\n e.preventDefault()\n this.showConfirmDialog(button, actionId, actionType, confirmTitle, confirmMessage)\n return\n }\n\n // 確認不要なら直接実行\n this.executeAction(button, actionId, actionType)\n }\n\n /**\n * 確認ダイアログを表示\n */\n private async showConfirmDialog(\n button: HTMLElement,\n actionId: string,\n actionType: string,\n title: string,\n message: string\n ): Promise<void> {\n const extendedConfig = this.deleteConfirmConfigs.get(actionId)\n\n // 依存データを取得\n let dependencies: DependencyInfo[] | undefined\n if (extendedConfig?.getDependencies) {\n const result = extendedConfig.getDependencies()\n dependencies = result instanceof Promise ? await result : result\n }\n\n // 削除対象名を取得\n let targetName = message\n if (extendedConfig?.getTargetName) {\n targetName = extendedConfig.getTargetName()\n }\n\n const config: DeleteConfirmDialogConfig = {\n title,\n targetName,\n targetType: extendedConfig?.targetType,\n dependencies,\n warningMessage: extendedConfig?.warningMessage,\n danger: true,\n }\n\n const dialog = new DeleteConfirmDialog(config, {\n onConfirm: () => {\n this.executeAction(button, actionId, actionType)\n },\n onCancel: () => {\n this.callbacks.onCancel?.(actionId)\n },\n })\n\n dialog.open()\n }\n\n /**\n * アクションを実行\n */\n private executeAction(button: HTMLElement, actionId: string, actionType: string): void {\n switch (actionType) {\n case 'submit': {\n const url = button.dataset.url\n const method = button.dataset.method\n this.callbacks.onSubmit?.(actionId, url, method)\n break\n }\n\n case 'navigate': {\n const to = button.dataset.navigateTo\n if (to) {\n this.callbacks.onNavigate?.(actionId, to)\n }\n break\n }\n\n case 'custom': {\n const handler = button.dataset.handler\n if (handler) {\n this.callbacks.onCustom?.(actionId, handler)\n }\n break\n }\n\n case 'reset': {\n this.callbacks.onReset?.(actionId)\n break\n }\n }\n }\n}\n\n// =============================================================================\n// Utility Functions\n// =============================================================================\n\n/**\n * コンテナにアクションハンドラーをアタッチ\n */\nexport function attachActionHandler(\n container: HTMLElement,\n callbacks: ActionHandlerCallbacks = {},\n deleteConfirmConfigs?: Map<string, DeleteConfirmExtendedConfig>\n): ActionHandler {\n const handler = new ActionHandler(container, callbacks, deleteConfirmConfigs)\n handler.attach()\n return handler\n}\n\n/**\n * 簡易的な確認ダイアログを表示(スタンドアロン使用)\n */\nexport function showDeleteConfirmDialog(\n config: DeleteConfirmDialogConfig,\n onConfirm: () => void,\n onCancel?: () => void\n): DeleteConfirmDialog {\n const dialog = new DeleteConfirmDialog(config, {\n onConfirm,\n onCancel,\n })\n dialog.open()\n return dialog\n}\n","/**\n * Mokkun - File Loader Module\n * YAMLファイルの読み込み機能を提供\n */\n\nimport { parseYaml, formatParseErrors } from '../parser'\nimport type { MokkunSchema } from '../types/schema'\nimport type { ParseError } from '../parser/yaml-parser'\n\n// ============================================================================\n// Types\n// ============================================================================\n\n/**\n * ファイル読み込みエラーの種類\n */\nexport type FileLoadErrorType =\n | 'INVALID_FILE_TYPE'\n | 'FILE_READ_ERROR'\n | 'FETCH_ERROR'\n | 'YAML_PARSE_ERROR'\n | 'NETWORK_ERROR'\n\n/**\n * ファイル読み込みエラー\n */\nexport interface FileLoadError {\n type: FileLoadErrorType\n message: string\n details?: string\n parseErrors?: ParseError[]\n}\n\n/**\n * ファイル読み込み成功結果\n */\nexport interface FileLoadSuccess {\n success: true\n schema: MokkunSchema\n fileName: string\n source: 'file' | 'url' | 'drop'\n}\n\n/**\n * ファイル読み込み失敗結果\n */\nexport interface FileLoadFailure {\n success: false\n error: FileLoadError\n}\n\n/**\n * ファイル読み込み結果\n */\nexport type FileLoadResult = FileLoadSuccess | FileLoadFailure\n\n/**\n * ファイル読み込みコールバック\n */\nexport type FileLoadCallback = (result: FileLoadResult) => void\n\n/**\n * ドロップゾーンオプション\n */\nexport interface DropZoneOptions {\n element: HTMLElement\n onLoad: FileLoadCallback\n onDragOver?: () => void\n onDragLeave?: () => void\n multiple?: boolean\n}\n\n/**\n * ファイル選択オプション\n */\nexport interface FileSelectOptions {\n onLoad: FileLoadCallback\n multiple?: boolean\n}\n\n// ============================================================================\n// Constants\n// ============================================================================\n\n/**\n * 許可されるファイル拡張子\n */\nconst ALLOWED_EXTENSIONS = ['.yaml', '.yml']\n\n/**\n * 許可されるMIMEタイプ\n */\nconst ALLOWED_MIME_TYPES = [\n 'application/x-yaml',\n 'application/yaml',\n 'text/yaml',\n 'text/x-yaml',\n 'text/plain', // 一部のブラウザでYAMLファイルがtext/plainとして認識される\n]\n\n/**\n * 許可されるプロトコル\n */\nconst ALLOWED_PROTOCOLS = ['https:', 'http:']\n\n/**\n * 最大ファイルサイズ (10MB)\n */\nconst MAX_FILE_SIZE = 10 * 1024 * 1024\n\n// ============================================================================\n// Validation\n// ============================================================================\n\n/**\n * ファイル名が許可された拡張子かチェック\n */\nexport function isValidFileName(fileName: string): boolean {\n const lowerName = fileName.toLowerCase()\n return ALLOWED_EXTENSIONS.some(ext => lowerName.endsWith(ext))\n}\n\n/**\n * ファイルタイプが許可されているかチェック\n */\nexport function isValidFileType(file: File): boolean {\n // MIMEタイプをチェック(空の場合はファイル名で判断)\n if (file.type && !ALLOWED_MIME_TYPES.includes(file.type)) {\n // ファイル名でフォールバックチェック\n return isValidFileName(file.name)\n }\n return isValidFileName(file.name)\n}\n\n/**\n * ファイルタイプエラーを生成\n */\nfunction createInvalidFileTypeError(fileName: string): FileLoadError {\n return {\n type: 'INVALID_FILE_TYPE',\n message: `無効なファイル形式: ${fileName}`,\n details: `YAMLファイル(${ALLOWED_EXTENSIONS.join(', ')})のみ対応しています`,\n }\n}\n\n// ============================================================================\n// YAML Content Processing\n// ============================================================================\n\n/**\n * YAMLテキストをパースしてスキーマを取得\n */\nfunction parseYamlContent(\n content: string,\n fileName: string,\n source: 'file' | 'url' | 'drop'\n): FileLoadResult {\n const result = parseYaml(content)\n\n if (!result.success) {\n return {\n success: false,\n error: {\n type: 'YAML_PARSE_ERROR',\n message: 'YAMLのパースに失敗しました',\n details: formatParseErrors(result.errors),\n parseErrors: result.errors,\n },\n }\n }\n\n return {\n success: true,\n schema: result.data,\n fileName,\n source,\n }\n}\n\n// ============================================================================\n// File Reading\n// ============================================================================\n\n/**\n * FileReaderでファイルを読み込み\n */\nexport function readFile(\n file: File,\n source: 'file' | 'drop'\n): Promise<FileLoadResult> {\n return new Promise(resolve => {\n // ファイルサイズチェック\n if (file.size > MAX_FILE_SIZE) {\n resolve({\n success: false,\n error: {\n type: 'FILE_READ_ERROR',\n message: `ファイルサイズが大きすぎます: ${file.name}`,\n details: `最大ファイルサイズは${MAX_FILE_SIZE / 1024 / 1024}MBです`,\n },\n })\n return\n }\n\n // ファイルタイプチェック\n if (!isValidFileType(file)) {\n resolve({\n success: false,\n error: createInvalidFileTypeError(file.name),\n })\n return\n }\n\n const reader = new FileReader()\n\n reader.onload = () => {\n const content = reader.result as string\n const result = parseYamlContent(content, file.name, source)\n resolve(result)\n }\n\n reader.onerror = () => {\n resolve({\n success: false,\n error: {\n type: 'FILE_READ_ERROR',\n message: `ファイルの読み込みに失敗しました: ${file.name}`,\n details: reader.error?.message ?? '不明なエラー',\n },\n })\n }\n\n reader.readAsText(file, 'UTF-8')\n })\n}\n\n/**\n * 複数ファイルを読み込み\n */\nexport async function readFiles(\n files: FileList | File[],\n source: 'file' | 'drop'\n): Promise<FileLoadResult[]> {\n const fileArray = Array.from(files)\n const results = await Promise.all(\n fileArray.map(file => readFile(file, source))\n )\n return results\n}\n\n// ============================================================================\n// URL Loading\n// ============================================================================\n\n/**\n * URLからYAMLファイルを読み込み\n */\nexport async function loadFromUrl(url: string): Promise<FileLoadResult> {\n // ファイル名を取得\n const urlObj = new URL(url, window.location.href)\n const pathParts = urlObj.pathname.split('/')\n const fileName = pathParts[pathParts.length - 1] || 'unknown.yaml'\n\n // プロトコルチェック\n if (!ALLOWED_PROTOCOLS.includes(urlObj.protocol)) {\n return {\n success: false,\n error: {\n type: 'FETCH_ERROR',\n message: '無効なURLプロトコル',\n details: `許可されているプロトコル: ${ALLOWED_PROTOCOLS.join(', ')}`,\n },\n }\n }\n\n // 拡張子チェック\n if (!isValidFileName(fileName)) {\n return {\n success: false,\n error: createInvalidFileTypeError(fileName),\n }\n }\n\n try {\n const response = await fetch(url)\n\n if (!response.ok) {\n return {\n success: false,\n error: {\n type: 'FETCH_ERROR',\n message: `ファイルの取得に失敗しました: ${url}`,\n details: `HTTPステータス: ${response.status} ${response.statusText}`,\n },\n }\n }\n\n const content = await response.text()\n return parseYamlContent(content, fileName, 'url')\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : String(error)\n return {\n success: false,\n error: {\n type: 'NETWORK_ERROR',\n message: `ネットワークエラー: ${url}`,\n details: errorMessage,\n },\n }\n }\n}\n\n/**\n * URLパラメータからYAMLパスを取得\n */\nexport function getYamlUrlFromParams(): string | null {\n const params = new URLSearchParams(window.location.search)\n return params.get('yaml')\n}\n\n/**\n * URLパラメータで指定されたYAMLを読み込み\n */\nexport async function loadFromUrlParams(): Promise<FileLoadResult | null> {\n const yamlPath = getYamlUrlFromParams()\n if (!yamlPath) {\n return null\n }\n return loadFromUrl(yamlPath)\n}\n\n// ============================================================================\n// File Selection Dialog\n// ============================================================================\n\n/**\n * ファイル選択input要素を作成\n */\nexport function createFileInput(options: FileSelectOptions): HTMLInputElement {\n const input = document.createElement('input')\n input.type = 'file'\n input.accept = ALLOWED_EXTENSIONS.join(',')\n input.multiple = options.multiple ?? false\n\n input.addEventListener('change', async () => {\n if (!input.files || input.files.length === 0) {\n return\n }\n\n if (options.multiple) {\n const results = await readFiles(input.files, 'file')\n results.forEach(result => options.onLoad(result))\n } else {\n const result = await readFile(input.files[0], 'file')\n options.onLoad(result)\n }\n\n // リセットして同じファイルを再選択可能に\n input.value = ''\n })\n\n return input\n}\n\n/**\n * ファイル選択ダイアログを開く\n */\nexport function openFileDialog(options: FileSelectOptions): void {\n const input = createFileInput(options)\n input.click()\n}\n\n// ============================================================================\n// Drag & Drop\n// ============================================================================\n\n/**\n * ドロップゾーンをセットアップ\n */\nexport function setupDropZone(options: DropZoneOptions): () => void {\n const { element, onLoad, onDragOver, onDragLeave, multiple = false } = options\n\n const handleDragOver = (e: DragEvent) => {\n e.preventDefault()\n e.stopPropagation()\n if (e.dataTransfer) {\n e.dataTransfer.dropEffect = 'copy'\n }\n element.classList.add('drag-over')\n onDragOver?.()\n }\n\n const handleDragLeave = (e: DragEvent) => {\n e.preventDefault()\n e.stopPropagation()\n element.classList.remove('drag-over')\n onDragLeave?.()\n }\n\n const handleDrop = async (e: DragEvent) => {\n e.preventDefault()\n e.stopPropagation()\n element.classList.remove('drag-over')\n onDragLeave?.()\n\n const files = e.dataTransfer?.files\n if (!files || files.length === 0) {\n return\n }\n\n if (multiple) {\n const results = await readFiles(files, 'drop')\n results.forEach(result => onLoad(result))\n } else {\n const result = await readFile(files[0], 'drop')\n onLoad(result)\n }\n }\n\n // イベントリスナーを登録\n element.addEventListener('dragover', handleDragOver)\n element.addEventListener('dragleave', handleDragLeave)\n element.addEventListener('drop', handleDrop)\n\n // クリーンアップ関数を返す\n return () => {\n element.removeEventListener('dragover', handleDragOver)\n element.removeEventListener('dragleave', handleDragLeave)\n element.removeEventListener('drop', handleDrop)\n }\n}\n\n// ============================================================================\n// Error Formatting\n// ============================================================================\n\n/**\n * エラーをフォーマットして表示用文字列に変換\n */\nexport function formatFileLoadError(error: FileLoadError): string {\n const lines = [error.message]\n\n if (error.details) {\n lines.push('')\n lines.push(error.details)\n }\n\n return lines.join('\\n')\n}\n\n// ============================================================================\n// UI Components\n// ============================================================================\n\n/**\n * ファイル読み込みUIを生成\n */\nexport function renderFileLoaderUI(): string {\n return `\n <div class=\"file-loader\">\n <div class=\"file-loader-header\">\n <h2>YAMLファイルを読み込む</h2>\n <p class=\"file-loader-description\">\n ファイルを選択、ドラッグ&ドロップ、またはURLで指定してください\n </p>\n </div>\n\n <div class=\"file-loader-options\">\n <div class=\"file-loader-dropzone\" id=\"yaml-dropzone\">\n <div class=\"dropzone-content\">\n <svg class=\"dropzone-icon\" viewBox=\"0 0 24 24\" width=\"48\" height=\"48\">\n <path fill=\"currentColor\" d=\"M19.35 10.04C18.67 6.59 15.64 4 12 4 9.11 4 6.6 5.64 5.35 8.04 2.34 8.36 0 10.91 0 14c0 3.31 2.69 6 6 6h13c2.76 0 5-2.24 5-5 0-2.64-2.05-4.78-4.65-4.96zM14 13v4h-4v-4H7l5-5 5 5h-3z\"/>\n </svg>\n <p class=\"dropzone-label\">ここにYAMLファイルをドロップ</p>\n <p class=\"dropzone-hint\">または</p>\n <button type=\"button\" class=\"btn btn-primary\" id=\"yaml-file-select\">\n ファイルを選択\n </button>\n </div>\n </div>\n\n <div class=\"file-loader-url\">\n <label for=\"yaml-url-input\" class=\"field-label\">URL指定</label>\n <div class=\"url-input-group\">\n <input\n type=\"url\"\n id=\"yaml-url-input\"\n class=\"form-input\"\n placeholder=\"https://example.com/form.yaml\"\n />\n <button type=\"button\" class=\"btn btn-secondary\" id=\"yaml-url-load\">\n 読み込み\n </button>\n </div>\n </div>\n </div>\n\n <div class=\"file-loader-info\">\n <p class=\"file-format-hint\">\n 対応形式: ${ALLOWED_EXTENSIONS.join(', ')}\n </p>\n </div>\n </div>\n `\n}\n\n/**\n * ファイルローダーUIにイベントをアタッチ\n */\nexport function attachFileLoaderEvents(\n container: HTMLElement,\n onLoad: FileLoadCallback\n): () => void {\n const dropzone = container.querySelector<HTMLElement>('#yaml-dropzone')\n const fileSelectBtn = container.querySelector<HTMLButtonElement>('#yaml-file-select')\n const urlInput = container.querySelector<HTMLInputElement>('#yaml-url-input')\n const urlLoadBtn = container.querySelector<HTMLButtonElement>('#yaml-url-load')\n\n const cleanupFunctions: Array<() => void> = []\n\n // ドロップゾーンのセットアップ\n if (dropzone) {\n const cleanup = setupDropZone({\n element: dropzone,\n onLoad,\n })\n cleanupFunctions.push(cleanup)\n }\n\n // ファイル選択ボタン\n if (fileSelectBtn) {\n const handleClick = () => {\n openFileDialog({ onLoad })\n }\n fileSelectBtn.addEventListener('click', handleClick)\n cleanupFunctions.push(() => fileSelectBtn.removeEventListener('click', handleClick))\n }\n\n // URL読み込みボタン\n if (urlLoadBtn && urlInput) {\n const handleUrlLoad = async () => {\n const url = urlInput.value.trim()\n if (!url) {\n return\n }\n const result = await loadFromUrl(url)\n onLoad(result)\n }\n urlLoadBtn.addEventListener('click', handleUrlLoad)\n cleanupFunctions.push(() => urlLoadBtn.removeEventListener('click', handleUrlLoad))\n\n // Enterキーでも読み込み\n const handleKeyPress = (e: KeyboardEvent) => {\n if (e.key === 'Enter') {\n handleUrlLoad()\n }\n }\n urlInput.addEventListener('keypress', handleKeyPress)\n cleanupFunctions.push(() => urlInput.removeEventListener('keypress', handleKeyPress))\n }\n\n // クリーンアップ関数を返す\n return () => {\n cleanupFunctions.forEach(fn => fn())\n }\n}\n","/**\n * Mokkun Theme Type Definitions\n * テーマ関連の型定義\n */\n\n/**\n * CSS Variables for theming\n */\nexport interface ThemeCSSVariables {\n '--primary-color'?: string\n '--primary-color-hover'?: string\n '--primary-color-light'?: string\n '--secondary-color'?: string\n '--secondary-color-hover'?: string\n '--background-color'?: string\n '--background-color-subtle'?: string\n '--surface-color'?: string\n '--text-color'?: string\n '--text-color-muted'?: string\n '--text-color-inverse'?: string\n '--border-color'?: string\n '--border-color-focus'?: string\n '--input-background'?: string\n '--input-border'?: string\n '--input-text'?: string\n '--input-placeholder'?: string\n '--button-background'?: string\n '--button-text'?: string\n '--button-secondary-background'?: string\n '--button-secondary-text'?: string\n '--button-secondary-border'?: string\n '--error-color'?: string\n '--error-color-light'?: string\n '--success-color'?: string\n '--success-color-light'?: string\n '--warning-color'?: string\n '--warning-color-light'?: string\n '--info-color'?: string\n '--info-color-light'?: string\n '--shadow-color'?: string\n '--shadow-sm'?: string\n '--shadow-md'?: string\n '--shadow-lg'?: string\n '--focus-ring-color'?: string\n '--scrollbar-track'?: string\n '--scrollbar-thumb'?: string\n '--scrollbar-thumb-hover'?: string\n [key: `--${string}`]: string | undefined\n}\n\n/**\n * Theme definition\n */\nexport interface ThemeDefinition {\n /** Unique theme ID */\n id: string\n /** Display name */\n name: string\n /** Description */\n description?: string\n /** Whether this is a built-in theme */\n isBuiltIn?: boolean\n /** Custom CSS variables (for custom themes) */\n cssVariables?: ThemeCSSVariables\n}\n\n/**\n * Built-in theme IDs\n */\nexport type BuiltInThemeId = 'light' | 'dark'\n\n/**\n * Theme configuration from YAML\n */\nexport interface ThemeConfig {\n /** Default theme ID */\n default_theme: string\n /** List of available themes */\n themes: ThemeConfigEntry[]\n /** Custom themes with CSS variables */\n custom_themes?: CustomThemeConfigEntry[]\n}\n\n/**\n * Theme entry in config\n */\nexport interface ThemeConfigEntry {\n id: string\n name: string\n description?: string\n}\n\n/**\n * Custom theme entry with CSS variables\n */\nexport interface CustomThemeConfigEntry extends ThemeConfigEntry {\n css_variables: Record<string, string>\n}\n\n/**\n * Theme change event detail\n */\nexport interface ThemeChangeEventDetail {\n previousTheme: string | null\n currentTheme: string\n}\n\n/**\n * Local storage key for theme preference\n */\nexport const THEME_STORAGE_KEY = 'mokkun-theme' as const\n\n/**\n * Data attribute for theme on document element\n */\nexport const THEME_DATA_ATTRIBUTE = 'data-theme' as const\n\n/**\n * Custom event name for theme changes\n */\nexport const THEME_CHANGE_EVENT = 'mokkun-theme-change' as const\n","/**\n * Mokkun Theme Manager\n * テーマの読み込み、切り替え、保存を管理\n */\n\nimport * as yaml from 'js-yaml'\nimport type {\n ThemeDefinition,\n ThemeConfig,\n ThemeCSSVariables,\n ThemeChangeEventDetail,\n BuiltInThemeId,\n} from '../types/theme'\nimport {\n THEME_STORAGE_KEY,\n THEME_DATA_ATTRIBUTE,\n THEME_CHANGE_EVENT,\n} from '../types/theme'\n\n/**\n * Built-in themes\n */\nconst BUILT_IN_THEMES: ThemeDefinition[] = [\n {\n id: 'light',\n name: 'ライト',\n description: 'デフォルトの明るいテーマ',\n isBuiltIn: true,\n },\n {\n id: 'dark',\n name: 'ダーク',\n description: '目に優しいダークテーマ',\n isBuiltIn: true,\n },\n]\n\n/**\n * Default theme ID\n */\nconst DEFAULT_THEME_ID: BuiltInThemeId = 'light'\n\n/**\n * Theme Manager class\n */\nexport class ThemeManager {\n private themes: Map<string, ThemeDefinition>\n private currentThemeId: string | null\n private config: ThemeConfig | null\n private customStyleElement: HTMLStyleElement | null\n\n constructor() {\n this.themes = new Map()\n this.currentThemeId = null\n this.config = null\n this.customStyleElement = null\n\n // Register built-in themes\n BUILT_IN_THEMES.forEach(theme => {\n this.themes.set(theme.id, theme)\n })\n }\n\n /**\n * Initialize the theme manager\n * Loads saved preference or applies default theme\n */\n initialize(): void {\n const savedTheme = this.getSavedTheme()\n const themeToApply = savedTheme && this.themes.has(savedTheme)\n ? savedTheme\n : this.config?.default_theme ?? DEFAULT_THEME_ID\n\n this.applyTheme(themeToApply)\n }\n\n /**\n * Load theme configuration from YAML string\n */\n loadConfig(yamlContent: string): void {\n try {\n this.config = yaml.load(yamlContent) as ThemeConfig\n\n // Register custom themes if any\n if (this.config.custom_themes) {\n this.config.custom_themes.forEach(customTheme => {\n const theme: ThemeDefinition = {\n id: customTheme.id,\n name: customTheme.name,\n description: customTheme.description,\n isBuiltIn: false,\n cssVariables: customTheme.css_variables as ThemeCSSVariables,\n }\n this.themes.set(theme.id, theme)\n })\n }\n } catch (error) {\n console.error('Failed to load theme config:', error)\n }\n }\n\n /**\n * Get all available themes\n */\n getAvailableThemes(): ThemeDefinition[] {\n return Array.from(this.themes.values())\n }\n\n /**\n * Get current theme ID\n */\n getCurrentTheme(): string | null {\n return this.currentThemeId\n }\n\n /**\n * Get theme by ID\n */\n getTheme(id: string): ThemeDefinition | undefined {\n return this.themes.get(id)\n }\n\n /**\n * Check if a theme exists\n */\n hasTheme(id: string): boolean {\n return this.themes.has(id)\n }\n\n /**\n * Apply a theme by ID\n */\n applyTheme(themeId: string): boolean {\n const theme = this.themes.get(themeId)\n if (!theme) {\n console.warn(`Theme not found: ${themeId}`)\n return false\n }\n\n const previousTheme = this.currentThemeId\n\n // Apply data attribute to document element\n document.documentElement.setAttribute(THEME_DATA_ATTRIBUTE, themeId)\n\n // Apply custom CSS variables if this is a custom theme\n if (!theme.isBuiltIn && theme.cssVariables) {\n this.applyCustomVariables(theme.cssVariables)\n } else {\n this.removeCustomVariables()\n }\n\n this.currentThemeId = themeId\n\n // Save to localStorage\n this.saveTheme(themeId)\n\n // Dispatch change event\n this.dispatchThemeChangeEvent(previousTheme, themeId)\n\n return true\n }\n\n /**\n * Apply custom CSS variables\n */\n private applyCustomVariables(variables: ThemeCSSVariables): void {\n this.removeCustomVariables()\n\n const styleContent = Object.entries(variables)\n .map(([key, value]) => ` ${key}: ${value};`)\n .join('\\n')\n\n const css = `[${THEME_DATA_ATTRIBUTE}] {\\n${styleContent}\\n}`\n\n this.customStyleElement = document.createElement('style')\n this.customStyleElement.id = 'mokkun-custom-theme'\n this.customStyleElement.textContent = css\n document.head.appendChild(this.customStyleElement)\n }\n\n /**\n * Remove custom CSS variables style element\n */\n private removeCustomVariables(): void {\n if (this.customStyleElement) {\n this.customStyleElement.remove()\n this.customStyleElement = null\n }\n }\n\n /**\n * Register a custom theme\n */\n registerTheme(theme: ThemeDefinition): void {\n this.themes.set(theme.id, {\n ...theme,\n isBuiltIn: false,\n })\n }\n\n /**\n * Unregister a theme (only custom themes can be removed)\n */\n unregisterTheme(themeId: string): boolean {\n const theme = this.themes.get(themeId)\n if (!theme || theme.isBuiltIn) {\n return false\n }\n\n this.themes.delete(themeId)\n\n // If current theme was removed, switch to default\n if (this.currentThemeId === themeId) {\n this.applyTheme(DEFAULT_THEME_ID)\n }\n\n return true\n }\n\n /**\n * Save theme preference to localStorage\n */\n private saveTheme(themeId: string): void {\n try {\n localStorage.setItem(THEME_STORAGE_KEY, themeId)\n } catch (error) {\n console.warn('Failed to save theme preference:', error)\n }\n }\n\n /**\n * Get saved theme from localStorage\n */\n getSavedTheme(): string | null {\n try {\n return localStorage.getItem(THEME_STORAGE_KEY)\n } catch (error) {\n console.warn('Failed to read theme preference:', error)\n return null\n }\n }\n\n /**\n * Clear saved theme preference\n */\n clearSavedTheme(): void {\n try {\n localStorage.removeItem(THEME_STORAGE_KEY)\n } catch (error) {\n console.warn('Failed to clear theme preference:', error)\n }\n }\n\n /**\n * Dispatch theme change event\n */\n private dispatchThemeChangeEvent(\n previousTheme: string | null,\n currentTheme: string\n ): void {\n const detail: ThemeChangeEventDetail = {\n previousTheme,\n currentTheme,\n }\n\n const event = new CustomEvent(THEME_CHANGE_EVENT, {\n bubbles: true,\n detail,\n })\n\n document.dispatchEvent(event)\n }\n\n /**\n * Subscribe to theme changes\n */\n onThemeChange(\n callback: (detail: ThemeChangeEventDetail) => void\n ): () => void {\n const handler = (event: Event) => {\n const customEvent = event as CustomEvent<ThemeChangeEventDetail>\n callback(customEvent.detail)\n }\n\n document.addEventListener(THEME_CHANGE_EVENT, handler)\n\n // Return unsubscribe function\n return () => {\n document.removeEventListener(THEME_CHANGE_EVENT, handler)\n }\n }\n\n /**\n * Get default theme ID\n */\n getDefaultTheme(): string {\n return this.config?.default_theme ?? DEFAULT_THEME_ID\n }\n\n /**\n * Check if system prefers dark mode\n */\n prefersColorScheme(): 'light' | 'dark' {\n if (typeof window === 'undefined' || typeof window.matchMedia !== 'function') {\n return 'light'\n }\n\n return window.matchMedia('(prefers-color-scheme: dark)').matches\n ? 'dark'\n : 'light'\n }\n\n /**\n * Apply system preference\n */\n applySystemPreference(): void {\n const preferred = this.prefersColorScheme()\n this.applyTheme(preferred)\n }\n\n /**\n * Watch for system preference changes\n */\n watchSystemPreference(autoApply: boolean = false): () => void {\n if (typeof window === 'undefined') {\n return () => {}\n }\n\n const mediaQuery = window.matchMedia('(prefers-color-scheme: dark)')\n\n const handler = (event: MediaQueryListEvent) => {\n if (autoApply) {\n this.applyTheme(event.matches ? 'dark' : 'light')\n }\n }\n\n mediaQuery.addEventListener('change', handler)\n\n return () => {\n mediaQuery.removeEventListener('change', handler)\n }\n }\n}\n\n// Export singleton instance\nexport const themeManager = new ThemeManager()\n\n// Export convenience functions\nexport const initializeTheme = () => themeManager.initialize()\nexport const applyTheme = (id: string) => themeManager.applyTheme(id)\nexport const getAvailableThemes = () => themeManager.getAvailableThemes()\nexport const getCurrentTheme = () => themeManager.getCurrentTheme()\nexport const onThemeChange = (\n callback: (detail: ThemeChangeEventDetail) => void\n) => themeManager.onThemeChange(callback)\n","/**\n * Mokkun Library Entry Point\n * YAML-based presentation and form builder\n */\n\n// Import CSS (will be handled by Vite)\nimport './style.css'\n\n// Import core modules\nimport { parseYaml, getScreen, getScreenNames, findFieldById } from './parser'\nimport {\n renderScreen,\n initializeSectionNav,\n mountWizardScreen,\n type SectionNavController,\n type WizardController,\n} from './renderer/screen-renderer'\nimport { attachActionHandler, type ActionHandlerCallbacks } from './renderer/action-handler'\nimport { loadFromUrl } from './loader'\nimport {\n initializeTheme,\n applyTheme,\n getAvailableThemes,\n getCurrentTheme,\n} from './theme'\nimport type { MokkunSchema, ScreenDefinition, BuiltInThemeId } from './types'\n\n// ============================================================================\n// Types\n// ============================================================================\n\n/**\n * Mokkun initialization options\n */\nexport interface MokkunInitOptions {\n /** Container selector or element */\n container: string | HTMLElement\n /** URL to YAML file */\n yamlUrl?: string\n /** Inline YAML content */\n yamlContent?: string\n /** Initial theme ('light' | 'dark') */\n theme?: BuiltInThemeId | string\n /** Initial screen to display */\n initialScreen?: string\n /** Callback when ready */\n onReady?: (instance: MokkunInstance) => void\n /** Callback on error */\n onError?: (error: Error) => void\n /** Callback when navigating between screens */\n onNavigate?: (fromScreen: string, toScreen: string) => void\n /** Callback when form is submitted */\n onSubmit?: (screenName: string, formData: Record<string, unknown>) => void\n}\n\n/**\n * Mokkun instance returned by init()\n */\nexport interface MokkunInstance {\n /** Current schema */\n readonly schema: MokkunSchema | null\n /** Current screen name */\n readonly currentScreen: string | null\n /** Navigate to a screen */\n showScreen: (screenName: string) => void\n /** Get available screen names */\n getScreenNames: () => string[]\n /** Change theme */\n setTheme: (themeId: string) => void\n /** Get current theme */\n getTheme: () => string | null\n /** Get current form data */\n getFormData: () => Record<string, unknown> | null\n /** Destroy instance and cleanup */\n destroy: () => void\n}\n\n// ============================================================================\n// Internal State\n// ============================================================================\n\ninterface InternalState {\n container: HTMLElement\n schema: MokkunSchema | null\n currentScreenName: string | null\n sectionNavController: SectionNavController | null\n wizardController: WizardController | null\n actionHandler: ReturnType<typeof attachActionHandler> | null\n options: MokkunInitOptions\n}\n\n// ============================================================================\n// Core Implementation\n// ============================================================================\n\n/**\n * Create a Mokkun instance with given state\n */\nfunction createInstance(state: InternalState): MokkunInstance {\n const renderCurrentScreen = (): void => {\n if (!state.schema || !state.currentScreenName) return\n\n const screen = getScreen(state.schema, state.currentScreenName)\n if (!screen) return\n\n // Cleanup previous controllers\n if (state.sectionNavController) {\n state.sectionNavController.destroy()\n state.sectionNavController = null\n }\n if (state.actionHandler) {\n state.actionHandler.detach()\n state.actionHandler = null\n }\n state.wizardController = null\n\n // Render screen\n if (screen.wizard) {\n state.wizardController = mountWizardScreen(state.container, screen, 0)\n } else {\n state.container.innerHTML = renderScreen(screen)\n\n // Initialize section nav if needed\n if (screen.sections && screen.sections.length > 0) {\n state.sectionNavController = initializeSectionNav(state.container, screen)\n }\n }\n\n // Attach action handler\n const callbacks: ActionHandlerCallbacks = {\n onNavigate: (_actionId, to) => {\n const fromScreen = state.currentScreenName\n instance.showScreen(to)\n if (fromScreen) {\n state.options.onNavigate?.(fromScreen, to)\n }\n },\n onSubmit: (_actionId, _url, _method) => {\n const formData = instance.getFormData()\n if (formData && state.currentScreenName) {\n state.options.onSubmit?.(state.currentScreenName, formData)\n }\n },\n onReset: () => {\n const form = state.container.querySelector('form')\n form?.reset()\n },\n onCancel: () => {},\n onCustom: () => {},\n }\n\n state.actionHandler = attachActionHandler(state.container, callbacks)\n }\n\n const instance: MokkunInstance = {\n get schema() {\n return state.schema\n },\n get currentScreen() {\n return state.currentScreenName\n },\n\n showScreen(screenName: string) {\n if (!state.schema) return\n const screen = getScreen(state.schema, screenName)\n if (!screen) {\n console.warn(`[Mokkun] Screen not found: ${screenName}`)\n return\n }\n state.currentScreenName = screenName\n renderCurrentScreen()\n },\n\n getScreenNames() {\n return state.schema ? getScreenNames(state.schema) : []\n },\n\n setTheme(themeId: string) {\n applyTheme(themeId)\n },\n\n getTheme() {\n return getCurrentTheme()\n },\n\n getFormData() {\n const form = state.container.querySelector('form')\n if (!form) return null\n const formData = new FormData(form)\n const data: Record<string, unknown> = {}\n formData.forEach((value, key) => {\n if (Object.prototype.hasOwnProperty.call(data, key)) {\n if (Array.isArray(data[key])) {\n ;(data[key] as unknown[]).push(value)\n } else {\n data[key] = [data[key], value]\n }\n } else {\n data[key] = value\n }\n })\n return data\n },\n\n destroy() {\n if (state.sectionNavController) {\n state.sectionNavController.destroy()\n }\n if (state.actionHandler) {\n state.actionHandler.detach()\n }\n state.container.innerHTML = ''\n state.schema = null\n state.currentScreenName = null\n state.sectionNavController = null\n state.wizardController = null\n state.actionHandler = null\n },\n }\n\n return instance\n}\n\n// ============================================================================\n// Public API\n// ============================================================================\n\n/**\n * Initialize Mokkun with the given options\n */\nasync function init(options: MokkunInitOptions): Promise<MokkunInstance> {\n // Resolve container\n const container =\n typeof options.container === 'string'\n ? document.querySelector<HTMLElement>(options.container)\n : options.container\n\n if (!container) {\n const error = new Error(`[Mokkun] Container not found: ${options.container}`)\n options.onError?.(error)\n throw error\n }\n\n // Initialize theme\n if (options.theme) {\n applyTheme(options.theme)\n } else {\n initializeTheme()\n }\n\n // Create internal state\n const state: InternalState = {\n container,\n schema: null,\n currentScreenName: null,\n sectionNavController: null,\n wizardController: null,\n actionHandler: null,\n options,\n }\n\n try {\n // Load YAML\n if (options.yamlContent) {\n const result = parseYaml(options.yamlContent)\n if (!result.success) {\n throw new Error(\n `[Mokkun] YAML parse error: ${result.errors.map((e) => e.message).join(', ')}`\n )\n }\n state.schema = result.data\n } else if (options.yamlUrl) {\n const result = await loadFromUrl(options.yamlUrl)\n if (!result.success) {\n throw new Error(`[Mokkun] Failed to load YAML: ${result.error.message}`)\n }\n state.schema = result.schema\n } else {\n throw new Error('[Mokkun] Either yamlUrl or yamlContent must be provided')\n }\n\n // Create instance\n const instance = createInstance(state)\n\n // Show initial screen\n const screenNames = instance.getScreenNames()\n const initialScreen =\n options.initialScreen && screenNames.includes(options.initialScreen)\n ? options.initialScreen\n : screenNames[0]\n\n if (initialScreen) {\n instance.showScreen(initialScreen)\n }\n\n // Call ready callback\n options.onReady?.(instance)\n\n return instance\n } catch (error) {\n const err = error instanceof Error ? error : new Error(String(error))\n options.onError?.(err)\n throw err\n }\n}\n\n// Version (replaced by Vite define)\ndeclare const __VERSION__: string\nconst VERSION = typeof __VERSION__ !== 'undefined' ? __VERSION__ : '0.0.0-dev'\n\n// ============================================================================\n// Main Export Object\n// ============================================================================\n\n/**\n * Mokkun - YAML-based presentation and form builder\n */\nexport const Mokkun = {\n /** Initialize Mokkun */\n init,\n /** Library version */\n VERSION,\n /** Utility functions */\n utils: {\n parseYaml,\n getScreen,\n getScreenNames,\n findFieldById,\n },\n /** Theme management */\n theme: {\n apply: applyTheme,\n getCurrent: getCurrentTheme,\n getAvailable: getAvailableThemes,\n },\n}\n\n// UMD global export\nif (typeof window !== 'undefined') {\n ;(window as unknown as { Mokkun: typeof Mokkun }).Mokkun = Mokkun\n}\n\nexport type { MokkunSchema, ScreenDefinition, BuiltInThemeId }\n\n// Export components\nexport {\n Textarea,\n createTextarea,\n type TextareaState,\n type TextareaCallbacks,\n type TextareaConfig,\n} from './renderer/components/textarea'\n\n// Export components for direct use\nexport {\n Combobox,\n type ComboboxOption,\n type ComboboxConfig,\n type ComboboxState,\n type ComboboxCallbacks,\n} from './renderer/components'\n"],"names":["isNothing","subject","isObject","toArray","sequence","extend","target","source","index","length","key","sourceKeys","repeat","string","count","result","cycle","isNegativeZero","number","isNothing_1","isObject_1","toArray_1","repeat_1","isNegativeZero_1","extend_1","common","formatError","exception","compact","where","message","YAMLException$1","reason","mark","getLine","buffer","lineStart","lineEnd","position","maxLineLength","head","tail","maxHalfLength","padStart","max","makeSnippet","options","re","lineStarts","lineEnds","match","foundLineNo","i","line","lineNoLength","snippet","TYPE_CONSTRUCTOR_OPTIONS","YAML_NODE_KINDS","compileStyleAliases","map","style","alias","Type$1","tag","name","data","type","compileList","schema","currentType","newIndex","previousType","previousIndex","compileMap","collectType","Schema$1","definition","implicit","explicit","type$1","str","seq","failsafe","resolveYamlNull","constructYamlNull","isNull","object","_null","resolveYamlBoolean","constructYamlBoolean","isBoolean","bool","isHexCode","c","isOctCode","isDecCode","resolveYamlInteger","hasDigits","ch","constructYamlInteger","value","sign","isInteger","int","obj","YAML_FLOAT_PATTERN","resolveYamlFloat","constructYamlFloat","SCIENTIFIC_WITHOUT_DOT","representYamlFloat","res","isFloat","float","json","core","YAML_DATE_REGEXP","YAML_TIMESTAMP_REGEXP","resolveYamlTimestamp","constructYamlTimestamp","year","month","day","hour","minute","second","fraction","delta","tz_hour","tz_minute","date","representYamlTimestamp","timestamp","resolveYamlMerge","merge","BASE64_MAP","resolveYamlBinary","code","idx","bitlen","constructYamlBinary","tailbits","input","bits","representYamlBinary","isBinary","binary","_hasOwnProperty$3","_toString$2","resolveYamlOmap","objectKeys","pair","pairKey","pairHasKey","constructYamlOmap","omap","_toString$1","resolveYamlPairs","keys","constructYamlPairs","pairs","_hasOwnProperty$2","resolveYamlSet","constructYamlSet","set","_default","_hasOwnProperty$1","CONTEXT_FLOW_IN","CONTEXT_FLOW_OUT","CONTEXT_BLOCK_IN","CONTEXT_BLOCK_OUT","CHOMPING_CLIP","CHOMPING_STRIP","CHOMPING_KEEP","PATTERN_NON_PRINTABLE","PATTERN_NON_ASCII_LINE_BREAKS","PATTERN_FLOW_INDICATORS","PATTERN_TAG_HANDLE","PATTERN_TAG_URI","_class","is_EOL","is_WHITE_SPACE","is_WS_OR_EOL","is_FLOW_INDICATOR","fromHexCode","lc","escapedHexLen","fromDecimalCode","simpleEscapeSequence","charFromCodepoint","setProperty","simpleEscapeCheck","simpleEscapeMap","State$1","generateError","state","throwError","throwWarning","directiveHandlers","args","major","minor","handle","prefix","captureSegment","start","end","checkJson","_position","_length","_character","_result","mergeMappings","destination","overridableKeys","quantity","storeMappingPair","keyTag","keyNode","valueNode","startLine","startLineStart","startPos","readLineBreak","skipSeparationSpace","allowComments","checkIndent","lineBreaks","testDocumentSeparator","writeFoldedLines","readPlainScalar","nodeIndent","withinFlowCollection","preceding","following","captureStart","captureEnd","hasPendingContent","_line","_lineStart","_lineIndent","_kind","readSingleQuotedScalar","readDoubleQuotedScalar","hexLength","hexResult","tmp","readFlowCollection","readNext","_pos","_tag","_anchor","terminator","isPair","isExplicitPair","isMapping","composeNode","readBlockScalar","folding","chomping","didReadContent","detectedIndent","textIndent","emptyLines","atMoreIndented","readBlockSequence","detected","readBlockMapping","flowIndent","allowCompact","_keyLine","_keyLineStart","_keyPos","atExplicitKey","readTagProperty","isVerbatim","isNamed","tagHandle","tagName","readAnchorProperty","readAlias","parentIndent","nodeContext","allowToSeek","allowBlockStyles","allowBlockScalars","allowBlockCollections","indentStatus","atNewLine","hasContent","typeIndex","typeQuantity","typeList","blockIndent","readDocument","documentStart","directiveName","directiveArgs","hasDirectives","loadDocuments","nullpos","loadAll$1","iterator","documents","load$1","loadAll_1","load_1","loader","_toString","_hasOwnProperty","CHAR_BOM","CHAR_TAB","CHAR_LINE_FEED","CHAR_CARRIAGE_RETURN","CHAR_SPACE","CHAR_EXCLAMATION","CHAR_DOUBLE_QUOTE","CHAR_SHARP","CHAR_PERCENT","CHAR_AMPERSAND","CHAR_SINGLE_QUOTE","CHAR_ASTERISK","CHAR_COMMA","CHAR_MINUS","CHAR_COLON","CHAR_EQUALS","CHAR_GREATER_THAN","CHAR_QUESTION","CHAR_COMMERCIAL_AT","CHAR_LEFT_SQUARE_BRACKET","CHAR_RIGHT_SQUARE_BRACKET","CHAR_GRAVE_ACCENT","CHAR_LEFT_CURLY_BRACKET","CHAR_VERTICAL_LINE","CHAR_RIGHT_CURLY_BRACKET","ESCAPE_SEQUENCES","DEPRECATED_BOOLEANS_SYNTAX","DEPRECATED_BASE60_SYNTAX","compileStyleMap","encodeHex","character","QUOTING_TYPE_SINGLE","QUOTING_TYPE_DOUBLE","State","indentString","spaces","ind","next","generateNextLine","level","testImplicitResolving","isWhitespace","isPrintable","isNsCharOrWhitespace","isPlainSafe","prev","inblock","cIsNsCharOrWhitespace","cIsNsChar","isPlainSafeFirst","isPlainSafeLast","codePointAt","pos","first","needIndentIndicator","leadingSpaceRe","STYLE_PLAIN","STYLE_SINGLE","STYLE_LITERAL","STYLE_FOLDED","STYLE_DOUBLE","chooseScalarStyle","singleLineOnly","indentPerLevel","lineWidth","testAmbiguousType","quotingType","forceQuotes","char","prevChar","hasLineBreak","hasFoldableLine","shouldTrackWidth","previousLineBreak","plain","writeScalar","iskey","indent","testAmbiguity","blockHeader","dropEndingNewline","foldString","escapeString","indentIndicator","clip","keep","chomp","width","lineRe","nextLF","foldLine","prevMoreIndented","moreIndented","breakRe","curr","escapeSeq","writeFlowSequence","writeNode","writeBlockSequence","writeFlowMapping","objectKeyList","objectKey","objectValue","pairBuffer","writeBlockMapping","explicitPair","detectType","block","isblockseq","tagStr","objectOrArray","duplicateIndex","duplicate","getDuplicateReferences","objects","duplicatesIndexes","inspectNode","dump$1","dump_1","dumper","renamed","from","to","Type","Schema","FAILSAFE_SCHEMA","JSON_SCHEMA","CORE_SCHEMA","DEFAULT_SCHEMA","load","loadAll","dump","YAMLException","types","safeLoad","safeLoadAll","safeDump","jsYaml","PLACEHOLDER_FIELD_TYPES","VALID_ACTION_TYPES","VALID_COMPONENT_TYPES","isDefined","isArray","isString","toSafeKey","normalizeInputField","raw","id","label","opt","base","fieldType","_a","t","_b","rawData","normalizedData","row","normalizeFieldsFromSections","sections","fields","section","rawField","createDataTableFromDisplayFields","displayFields","filters","screenName","columns","fieldName","filterConfig","f","filterName","normalizeSection","rawSection","normalizeAppHeader","nav","item","normalizeAppNavi","items","dropdownItem","normalizeScreenDefinition","title","actions","action","normalizeView","view","screen","normalizeCommonComponents","components","comp","normalizeValidations","validations","rule","normalizeSchema","validateInputField","field","path","errors","isPlaceholderType","isDisplayOnlyType","option","validateSelectOption","itemField","validateAction","validateWizard","wizard","step","validateWizardStep","validateScreenDefinition","validateCommonComponent","component","validateValidationRule","validateScreenDefinitionArray","validateCommonComponentArray","validateValidationRuleArray","validateSchema","componentName","ruleName","parseYaml","yamlText","yaml","error","formatParseErrors","location","getScreen","getScreenNames","findFieldById","fieldId","found","createElement","element","child","clearElement","generateId","escapeHtml","text","div","createFieldWrapper","content","requiredMark","description","classes","visibleWhenAttr","getCommonAttributes","attrs","getOptions","formatFileSize","bytes","formatMimeType","mimeType","getDefaultSizeForLevel","unitLabels","Input","container","config","callbacks","__publicField","size","hasPrefix","hasSuffix","wrapper","inputGroup","errorElement","errorMessage","disabled","readonly","prefixElement","clearButton","suffixElement","affix","affixWrapper","button","icon","event","existingClearButton","existingSuffix","shouldShowClear","inputType","Textarea","textarea","counter","errorEl","rows","resizableClass","e","characterCount","maxLength","scrollHeight","resizeClass","defaultValue","createTextarea","isOptionGroup","Select","select","stringValue","classNames","blankOption","optgroup","group","sizeClass","grouped","ungrouped","renderOption","selected","ungroupedHtml","groupedHtml","opts","optionsHtml","defaultValues","optionHtml","RadioButton","labelPosition","dataState","radio","checked","_d","_c","radioContainer","visualRadio","circle","dot","checkedLabel","uncheckedLabel","labelText","direction","optionId","descriptionHtml","Checkbox","checkbox","indeterminate","checkboxContainer","visualCheckbox","box","checkboxInput","Combobox","initialValues","values","allOptions","filteredOptions","partial","query","normalized","labelMatch","descMatch","groupMatch","minLength","control","valueContainer","tagsContainer","selectedOption","singleValue","indicators","attributes","selectedOptions","removeBtn","clearBtn","separator","dropdownBtn","dropdown","loading","empty","globalIndex","groupName","header","optionEl","isSelected","isHighlighted","el","desc","btn","maxSelections","v","lastValue","nextIndex","prevIndex","prevEl","newEl","optionListId","Heading","align","color","headingElement","iconSpan","textSpan","iconHtml","DurationPicker","unit","unitElement","unitContainer","unitId","currentValue","units","_","DurationInput","unitLabel","Pagination","pageSizeSelector","navigation","itemCount","page","newPage","pageSize","firstItemIndex","totalPages","totalItems","maxPage","currentPage","showJumpButtons","firstButton","prevButton","nextButton","lastButton","maxButtons","buttons","pages","previousPage","ellipsis","sideButtons","a","b","isActive","span","paginationField","startItem","endItem","paginationHtml","Toggle","toggle","toggleContainer","stateClass","toggleSwitch","track","thumb","toggleField","toggleHtml","Badge","clickable","badge","hidden","hideOnZero","ariaLabel","displayCount","maxCount","badgeField","badgeHtml","Browser","initialPath","parentValue","maxColumns","selectedValue","columnData","columnIndex","column","itemIndex","itemElement","isLeafSelected","hasChildren","isFocused","itemWrapper","labelContainer","arrow","svg","newPath","rowDelta","colDelta","columnsData","newColumnIndex","newItemIndex","currentColumn","selector","Calendar","calendar","grid","displayedMonth","monthLabel","weekdayRow","weeks","week","weekRow","weekdays","weekday","cell","isToday","isDisabled","isOutOfRange","isCurrentMonth","newDate","baseDate","newMonth","firstDay","lastDay","weekStartsOn","startDate","diff","weekDays","currentDate","lastDayOfWeek","firstDayOfNextWeek","locale","labels","dayIndex","today","_date","normalizedDate","days","calendarHtml","Tooltip","triggerElement","triggerRect","tooltipRect","gap","top","left","viewportWidth","viewportHeight","tooltipField","tooltipHtml","FloatArea","containerElement","zIndex","innerContainer","tertiaryWrapper","mainArea","messageEl","buttonGroup","variant","_e","_g","_f","iconEl","textEl","Loader","clampedValue","contentContainer","progressContainer","progress","loaderField","loaderHtml","BUILTIN_ICONS","CLOSE_ICON","NotificationBar","bold","closable","role","actionButton","closeButton","visible","notificationField","dismissible","notificationHtml","ICONS","CHEVRON_DOWN","RETRY_ICON","LOADING_ICON","ANIMATION_DURATION_MS","ResponseMessage","contentEl","closeEl","details","toggleBtn","retryBtn","closeBtn","actionsEl","detailsEl","labelSpan","chevronSpan","retryFn","detailsWrapper","listEl","li","trimmed","doc","dangerousAttrs","attr","svgHref","href","messageHtml","toDate","datetime","formatDate","formatTime","format","hours","minutes","seconds","sanitizeHtml","src","sanitizedStyle","sanitizeSvgIcon","Timeline","list","itemEl","existingItem","currentIndex","handler","isFirst","isLast","isCurrent","markerArea","contentArea","iconWrapper","dateArea","dateLabel","dateEl","timeFormat","timeStr","timeEl","suffixEl","sideActionEl","builtinIcon","Chip","chipElement","chipWrapper","chipContent","iconElement","labelElement","deleteButton","deleteIcon","newSelected","updates","newState","chipField","removable","chipHtml","StatusLabel","iconPosition","sanitizedSvg","statusHtml","SegmentedControl","optionsContainer","optionElement","isFocusable","optionIndex","segmentedField","segmentedHtml","Tabs","bordered","scrollable","tabList","panels","tabId","tab","newTabs","newActiveTabId","enabledTab","initialTabId","tabButton","className","panel","fieldEl","isVertical","firstEnabled","lastEnabled","hash","loadingDiv","currentPanel","errorDiv","html","allowedTags","allowedAttributes","sanitizeNode","node","fragment","sanitizedChild","newElement","allowedAttrs","tempDiv","isValidMaxLines","LineClamp","maxLines","clamped","lineClampHtml","escapeHtmlHelper","Disclosure","labelOpen","labelEl","triggerId","contentId","trigger","disclosureHtml","AccordionPanel","headingType","expandableMultiply","previouslyExpanded","prevName","n","enabledItems","previousExpanded","validNames","defaultExpanded","isExpanded","titleIcon","elements","contentPanel","nextEnabledIndex","nextItem","currentEnabledIndex","previousEnabledIndex","previousItem","accordionHtml","DEFAULT_SCROLL_OFFSET","SCROLL_DEBOUNCE_MS","DEFAULT_ROOT_MARGIN","SectionNav","mobileMode","stickyTop","navList","sectionId","s","targetElement","offset","behavior","targetPosition","newSections","newActiveSectionId","enabledSection","ul","activeSection","chevron","menu","optionLabel","rootMargin","threshold","entries","entry","dropdownTrigger","sectionNavHtml","DefinitionList","layout","striped","groups","isGrouped","groupIndex","groupElement","groupContainer","titleElement","listContainer","emptyText","termStyleType","sanitizedClassName","termElement","descriptionElement","listItem","definitionHtml","getStatusType","status","getStatusAltText","createCheckIcon","createCloseIcon","Stepper","_callbacks","ol","isPast","statusType","isCompleted","isClosed","isPrevCompleted","labelWrapper","counterWrapper","beforeLine","afterLine","counterArea","body","heading","inner","hasStatus","InformationPanel","toggleable","defaultActive","toggleButton","contentInner","infoHtml","Dropdown","placement","triggerSize","isOpen","onlyIcon","isFiltered","caret","filterContent","resetButton","applyButton","menuItem","indicator","newDirection","selectedFilters","actionableItems","firstIndex","focusedElement","actionableCount","lastIndex","nextActionableIndex","currentActionableIndex","previousActionableIndex","dropdownHtml","DeleteConfirmDialog","dangerClass","targetInfo","targetTypeLabel","targetText","dependenciesSection","warning","warningIcon","warningText","dep","d","affectedNote","footer","cancelBtn","confirmBtn","focusableElements","firstElement","lastElement","activeElement","dialogField","cancelLabel","confirmLabel","targetName","dialogHtml","getFaker","generateDummyValueForColumn","rowIndex","faker","lowerLabel","statuses","generateDataTableDummyRow","generateDataTableDummyData","rowCount","formatCellValue","currency","statusInfo","getStatusBadgeClass","getFixedHeaderConfig","getResizeConfig","renderRowActions","styleClass","renderDataTableField","fixedHeaderConfig","resizeConfig","tableId","dummyRowCount","heightStyle","headerCells","sortable","alignClass","fixedClass","widthStyle","resizeHandle","colspanAttr","rowspanAttr","selectionHeader","actionsHeader","bodyContent","emptyState","totalColumns","actionHtml","cells","fieldKey","formattedValue","statusClass","cellMerge","cellContent","selectionCell","actionsCell","stickyStyle","theadClass","tbodyClass","renderPhotoManagerField","managerId","photos","maxPhotos","maxFileSize","acceptedFormats","uploadAreaHtml","counterHtml","dragHintHtml","photosHtml","photo","isMain","renderFileUploadField","dropzoneClass","maxSizeMB","renderGoogleMapEmbedFieldHtml","height","showOpenLink","renderImageUploaderField","maxFiles","formatsDisplay","sizeDisplay","renderRepeaterFieldStatic","itemFields","maxItems","addLabel","itemFieldsHtml","renderField","counterText","renderFields","getButtonClass","renderAction","buttonClass","dataAttrs","renderActions","getLayoutStyle","styles","renderScreenHeader","renderFieldsSection","layoutStyle","fieldsHtml","renderActionsSection","renderWizardProgress","currentStepIndex","renderWizardStep","stepIndex","isFirstStep","isLastStep","allowBack","backButton","submitButton","renderWizardScreen","renderScreen","progressHtml","stepHtml","generateSectionId","sectionName","renderSectionsScreen","appLayoutHtml","renderAppLayoutContainers","headerHtml","actionsHtml","sectionsHtml","publishToggleHtml","appHeaderHtml","appNaviHtml","initializeSectionNav","navContainer","sectionNav","mountWizardScreen","initialStep","currentStep","render","attachWizardEventListeners","ActionHandler","deleteConfirmConfigs","actionId","actionType","confirmTitle","confirmMessage","extendedConfig","dependencies","url","method","_h","attachActionHandler","ALLOWED_EXTENSIONS","ALLOWED_PROTOCOLS","isValidFileName","fileName","lowerName","ext","createInvalidFileTypeError","parseYamlContent","loadFromUrl","urlObj","pathParts","response","THEME_STORAGE_KEY","THEME_DATA_ATTRIBUTE","THEME_CHANGE_EVENT","BUILT_IN_THEMES","DEFAULT_THEME_ID","ThemeManager","theme","savedTheme","themeToApply","yamlContent","yaml.load","customTheme","themeId","previousTheme","variables","styleContent","css","currentTheme","detail","callback","preferred","autoApply","mediaQuery","themeManager","initializeTheme","applyTheme","getAvailableThemes","getCurrentTheme","createInstance","renderCurrentScreen","_actionId","fromScreen","instance","_url","_method","formData","form","init","screenNames","initialScreen","err","Mokkun"],"mappings":"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","x_google_ignoreList":[0]}