From 1d7d3ae699ad424dbb85bb93bcf9733ea00b93a4 Mon Sep 17 00:00:00 2001 From: Mattes Mohr Date: Sat, 3 Aug 2024 11:17:54 +0200 Subject: [PATCH 1/3] Make the textpad responsive --- .../HTMLKitComponents/Components/Form.swift | 290 ++++++++++++------ .../Resources/css/forms/textpad.css | 110 ++++++- .../Resources/js/components/forms/textpad.js | 55 +++- 3 files changed, 350 insertions(+), 105 deletions(-) diff --git a/Sources/HTMLKitComponents/Components/Form.swift b/Sources/HTMLKitComponents/Components/Form.swift index 4745cfef..98b65314 100644 --- a/Sources/HTMLKitComponents/Components/Form.swift +++ b/Sources/HTMLKitComponents/Components/Form.swift @@ -1397,133 +1397,241 @@ public struct TextPad: View, Modifiable, Identifiable { public var body: Content { Division { - Menu { - ListItem { - HTMLKit.Button { + Division { + Details { + Summary { Vector { Path { Title { - "Bold emphasis command" + "More options" } } - .draw("M4.25,14.25L4.25,1.75C4.25,1.336 4.586,1 5,1L10.769,1C12.646,1 14.212,2.659 14.212,4.75C14.212,5.686 13.898,6.785 13.383,7.438C14.746,7.929 15.75,9.576 15.75,11.25C15.75,13.341 14.184,15 12.308,15L5,15C4.586,15 4.25,14.664 4.25,14.25ZM10.769,2.5L5.75,2.5C5.75,2.5 5.75,7.25 5.75,7.25L10.769,7.25C11.865,7.25 12.712,5.971 12.712,4.75C12.712,3.529 11.865,2.5 10.769,2.5ZM14.25,11.25C14.25,10.029 13.403,8.75 12.308,8.75L5.75,8.75C5.75,8.75 5.75,13.5 5.75,13.5L12.308,13.5C13.403,13.5 14.25,12.471 14.25,11.25Z") + .draw("M15.5,6.5C16.328,6.5 17,7.172 17,8C17,8.828 16.328,9.5 15.5,9.5C14.672,9.5 14,8.828 14,8C14,7.172 14.672,6.5 15.5,6.5ZM10,6.5C10.828,6.5 11.5,7.172 11.5,8C11.5,8.828 10.828,9.5 10,9.5C9.172,9.5 8.5,8.828 8.5,8C8.5,7.172 9.172,6.5 10,6.5ZM4.5,6.5C5.328,6.5 6,7.172 6,8C6,8.828 5.328,9.5 4.5,9.5C3.672,9.5 3,8.828 3,8C3,7.172 3.672,6.5 4.5,6.5Z") } .namespace("http://www.w3.org/2000/svg") .viewBox("0 0 20 16") } - .type(.button) - .title("Bold") - .class("toolbar-tool") - .custom(key: "data-command", value: "bold") - } - ListItem { - HTMLKit.Button { - Vector { - Path { - Title { - "Italic emphasis command" + UnorderedList { + ListItem { + HTMLKit.Button { + Vector { + Path { + Title { + "Bold" + } + } + .draw("M4.25,14.25L4.25,1.75C4.25,1.336 4.586,1 5,1L10.769,1C12.646,1 14.212,2.659 14.212,4.75C14.212,5.686 13.898,6.785 13.383,7.438C14.746,7.929 15.75,9.576 15.75,11.25C15.75,13.341 14.184,15 12.308,15L5,15C4.586,15 4.25,14.664 4.25,14.25ZM10.769,2.5L5.75,2.5C5.75,2.5 5.75,7.25 5.75,7.25L10.769,7.25C11.865,7.25 12.712,5.971 12.712,4.75C12.712,3.529 11.865,2.5 10.769,2.5ZM14.25,11.25C14.25,10.029 13.403,8.75 12.308,8.75L5.75,8.75C5.75,8.75 5.75,13.5 5.75,13.5L12.308,13.5C13.403,13.5 14.25,12.471 14.25,11.25Z") } + .namespace("http://www.w3.org/2000/svg") + .viewBox("0 0 20 16") } - .draw("M8.989,15L4,15C3.586,15 3.25,14.664 3.25,14.25C3.25,13.836 3.586,13.5 4,13.5L8.36,13.5L10.12,2.5L6,2.5C5.586,2.5 5.25,2.164 5.25,1.75C5.25,1.336 5.586,1 6,1C6,1 11.003,1 11.011,1L16,1C16.414,1 16.75,1.336 16.75,1.75C16.75,2.164 16.414,2.5 16,2.5L11.64,2.5L9.88,13.5L14,13.5C14.414,13.5 14.75,13.836 14.75,14.25C14.75,14.664 14.414,15 14,15C14,15 8.997,15 8.989,15Z") + .type(.button) + .class("toolbar-tool") + .custom(key: "data-command", value: "bold") + } + ListItem { + HTMLKit.Button { + Vector { + Path { + Title { + "Italic" + } + } + .draw("M8.989,15L4,15C3.586,15 3.25,14.664 3.25,14.25C3.25,13.836 3.586,13.5 4,13.5L8.36,13.5L10.12,2.5L6,2.5C5.586,2.5 5.25,2.164 5.25,1.75C5.25,1.336 5.586,1 6,1C6,1 11.003,1 11.011,1L16,1C16.414,1 16.75,1.336 16.75,1.75C16.75,2.164 16.414,2.5 16,2.5L11.64,2.5L9.88,13.5L14,13.5C14.414,13.5 14.75,13.836 14.75,14.25C14.75,14.664 14.414,15 14,15C14,15 8.997,15 8.989,15Z") + } + .namespace("http://www.w3.org/2000/svg") + .viewBox("0 0 20 16") + } + .type(.button) + .class("toolbar-tool") + .custom(key: "data-command", value: "italic") + } + ListItem { + HTMLKit.Button { + Vector { + Path { + Title { + "Strikethrough" + } + } + .draw("M6.068,7C5.894,6.829 5.745,6.646 5.621,6.45C5.305,5.95 5.148,5.39 5.148,4.771C5.148,4.09 5.341,3.454 5.727,2.862C6.113,2.27 6.678,1.821 7.42,1.514C8.162,1.208 8.987,1.054 9.894,1.054C10.894,1.054 11.775,1.215 12.539,1.537C13.302,1.859 13.89,2.333 14.301,2.959C14.711,3.584 14.932,4.292 14.963,5.083L13.252,5.212C13.16,4.36 12.849,3.716 12.318,3.28C11.788,2.845 11.004,2.627 9.968,2.627C8.888,2.627 8.102,2.825 7.608,3.221C7.115,3.616 6.868,4.093 6.868,4.651C6.868,5.136 7.043,5.534 7.392,5.847C7.736,6.16 8.632,6.48 10.083,6.808C10.373,6.874 10.644,6.938 10.898,7L6.068,7ZM14.776,9C14.787,9.014 14.797,9.029 14.806,9.044C15.181,9.599 15.368,10.238 15.368,10.962C15.368,11.679 15.162,12.355 14.751,12.99C14.34,13.625 13.75,14.118 12.98,14.471C12.211,14.824 11.345,15 10.382,15C9.161,15 8.139,14.822 7.314,14.466C6.489,14.111 5.842,13.576 5.373,12.861C4.904,12.147 4.657,11.339 4.632,10.437L6.316,10.29C6.396,10.965 6.581,11.518 6.872,11.951C7.164,12.383 7.616,12.732 8.229,12.999C8.842,13.266 9.532,13.399 10.299,13.399C10.98,13.399 11.581,13.298 12.102,13.096C12.623,12.893 13.011,12.616 13.266,12.263C13.52,11.911 13.647,11.526 13.647,11.109C13.647,10.686 13.525,10.316 13.279,10C13.034,9.685 12.629,9.419 12.065,9.205C11.922,9.149 11.709,9.081 11.428,9L14.776,9ZM17,7.277L17,8.777L3,8.777L3,7.277L17,7.277Z") + } + .namespace("http://www.w3.org/2000/svg") + .viewBox("0 0 20 16") + } + .type(.button) + .class("toolbar-tool") + .custom(key: "data-command", value: "strikethrough") + } + ListItem { + HTMLKit.Button { + Vector { + Path { + Title { + "Link" + } + } + .draw("M10.025,11.51C9.368,11.335 8.747,10.99 8.232,10.475L7.525,9.768C5.964,8.207 5.964,5.672 7.525,4.111L10.354,1.282C11.915,-0.279 14.449,-0.279 16.01,1.282L16.718,1.99C18.279,3.551 18.279,6.085 16.718,7.646L13.933,10.431C14.165,9.703 14.207,8.928 14.06,8.183L15.303,6.939C16.474,5.769 16.474,3.867 15.303,2.697C14.133,1.526 12.231,1.526 11.061,2.697L8.939,4.818C7.769,5.989 7.769,7.89 8.939,9.061C9.581,9.703 10.443,9.993 11.283,9.931C11.162,10.258 10.97,10.565 10.707,10.828L10.025,11.51ZM9.975,4.49C10.632,4.665 11.253,5.01 11.768,5.525L12.475,6.232C14.036,7.793 14.036,10.328 12.475,11.889L9.646,14.718C8.085,16.279 5.551,16.279 3.99,14.718L3.282,14.01C1.721,12.449 1.721,9.915 3.282,8.354L6.067,5.569C5.835,6.297 5.793,7.072 5.94,7.817L4.697,9.061C3.526,10.231 3.526,12.133 4.697,13.303C5.867,14.474 7.769,14.474 8.939,13.303L11.061,11.182C12.231,10.011 12.231,8.11 11.061,6.939C10.419,6.297 9.557,6.007 8.717,6.069C8.838,5.742 9.03,5.435 9.293,5.172L9.975,4.49Z") + } + .namespace("http://www.w3.org/2000/svg") + .viewBox("0 0 20 16") + } + .type(.button) + .class("toolbar-tool") + .custom(key: "data-command", value: "link") + } + ListItem { + HTMLKit.Button { + Vector { + Path { + Title { + "Code emphasis command" + } + } + .draw("M11.829,2.171C11.57,1.848 11.623,1.376 11.946,1.117C12.269,0.859 12.741,0.911 13,1.234L17.546,7.532C17.765,7.805 17.765,8.195 17.546,8.469L13.171,14.883C12.913,15.206 12.44,15.259 12.117,15C11.794,14.741 11.741,14.269 12,13.946C12,13.946 16,8 16,8L11.829,2.171ZM8.288,13.946C8.547,14.269 8.495,14.741 8.171,15C7.848,15.259 7.376,15.206 7.117,14.883L2.454,8.469C2.235,8.195 2.235,7.805 2.454,7.532L6.946,1.351C7.204,1.028 7.677,0.976 8,1.234C8.323,1.493 8.376,1.965 8.117,2.288C8.117,2.288 4,8 4,8L8.288,13.946Z") + } + .namespace("http://www.w3.org/2000/svg") + .viewBox("0 0 20 16") + } + .type(.button) + .class("toolbar-tool") + .custom(key: "data-command", value: "code") } - .namespace("http://www.w3.org/2000/svg") - .viewBox("0 0 20 16") } - .type(.button) - .title("Italic") - .class("toolbar-tool") - .custom(key: "data-command", value: "italic") } - ListItem { - HTMLKit.Button { - Vector { - Path { - Title { - "Strikethrough emphasis command" + .class("toolbar-context") + Menu { + ListItem { + HTMLKit.Button { + Vector { + Path { + Title { + "Bold emphasis command" + } } + .draw("M4.25,14.25L4.25,1.75C4.25,1.336 4.586,1 5,1L10.769,1C12.646,1 14.212,2.659 14.212,4.75C14.212,5.686 13.898,6.785 13.383,7.438C14.746,7.929 15.75,9.576 15.75,11.25C15.75,13.341 14.184,15 12.308,15L5,15C4.586,15 4.25,14.664 4.25,14.25ZM10.769,2.5L5.75,2.5C5.75,2.5 5.75,7.25 5.75,7.25L10.769,7.25C11.865,7.25 12.712,5.971 12.712,4.75C12.712,3.529 11.865,2.5 10.769,2.5ZM14.25,11.25C14.25,10.029 13.403,8.75 12.308,8.75L5.75,8.75C5.75,8.75 5.75,13.5 5.75,13.5L12.308,13.5C13.403,13.5 14.25,12.471 14.25,11.25Z") } - .draw("M6.068,7C5.894,6.829 5.745,6.646 5.621,6.45C5.305,5.95 5.148,5.39 5.148,4.771C5.148,4.09 5.341,3.454 5.727,2.862C6.113,2.27 6.678,1.821 7.42,1.514C8.162,1.208 8.987,1.054 9.894,1.054C10.894,1.054 11.775,1.215 12.539,1.537C13.302,1.859 13.89,2.333 14.301,2.959C14.711,3.584 14.932,4.292 14.963,5.083L13.252,5.212C13.16,4.36 12.849,3.716 12.318,3.28C11.788,2.845 11.004,2.627 9.968,2.627C8.888,2.627 8.102,2.825 7.608,3.221C7.115,3.616 6.868,4.093 6.868,4.651C6.868,5.136 7.043,5.534 7.392,5.847C7.736,6.16 8.632,6.48 10.083,6.808C10.373,6.874 10.644,6.938 10.898,7L6.068,7ZM14.776,9C14.787,9.014 14.797,9.029 14.806,9.044C15.181,9.599 15.368,10.238 15.368,10.962C15.368,11.679 15.162,12.355 14.751,12.99C14.34,13.625 13.75,14.118 12.98,14.471C12.211,14.824 11.345,15 10.382,15C9.161,15 8.139,14.822 7.314,14.466C6.489,14.111 5.842,13.576 5.373,12.861C4.904,12.147 4.657,11.339 4.632,10.437L6.316,10.29C6.396,10.965 6.581,11.518 6.872,11.951C7.164,12.383 7.616,12.732 8.229,12.999C8.842,13.266 9.532,13.399 10.299,13.399C10.98,13.399 11.581,13.298 12.102,13.096C12.623,12.893 13.011,12.616 13.266,12.263C13.52,11.911 13.647,11.526 13.647,11.109C13.647,10.686 13.525,10.316 13.279,10C13.034,9.685 12.629,9.419 12.065,9.205C11.922,9.149 11.709,9.081 11.428,9L14.776,9ZM17,7.277L17,8.777L3,8.777L3,7.277L17,7.277Z") + .namespace("http://www.w3.org/2000/svg") + .viewBox("0 0 20 16") } - .namespace("http://www.w3.org/2000/svg") - .viewBox("0 0 20 16") + .type(.button) + .title("Bold") + .class("toolbar-tool") + .custom(key: "data-command", value: "bold") } - .type(.button) - .title("Strikethrough") - .class("toolbar-tool") - .custom(key: "data-command", value: "strikethrough") - } - ListItem { - HTMLKit.Button { - Vector { - Path { - Title { - "Link reference command" + ListItem { + HTMLKit.Button { + Vector { + Path { + Title { + "Italic emphasis command" + } } + .draw("M8.989,15L4,15C3.586,15 3.25,14.664 3.25,14.25C3.25,13.836 3.586,13.5 4,13.5L8.36,13.5L10.12,2.5L6,2.5C5.586,2.5 5.25,2.164 5.25,1.75C5.25,1.336 5.586,1 6,1C6,1 11.003,1 11.011,1L16,1C16.414,1 16.75,1.336 16.75,1.75C16.75,2.164 16.414,2.5 16,2.5L11.64,2.5L9.88,13.5L14,13.5C14.414,13.5 14.75,13.836 14.75,14.25C14.75,14.664 14.414,15 14,15C14,15 8.997,15 8.989,15Z") } - .draw("M10.025,11.51C9.368,11.335 8.747,10.99 8.232,10.475L7.525,9.768C5.964,8.207 5.964,5.672 7.525,4.111L10.354,1.282C11.915,-0.279 14.449,-0.279 16.01,1.282L16.718,1.99C18.279,3.551 18.279,6.085 16.718,7.646L13.933,10.431C14.165,9.703 14.207,8.928 14.06,8.183L15.303,6.939C16.474,5.769 16.474,3.867 15.303,2.697C14.133,1.526 12.231,1.526 11.061,2.697L8.939,4.818C7.769,5.989 7.769,7.89 8.939,9.061C9.581,9.703 10.443,9.993 11.283,9.931C11.162,10.258 10.97,10.565 10.707,10.828L10.025,11.51ZM9.975,4.49C10.632,4.665 11.253,5.01 11.768,5.525L12.475,6.232C14.036,7.793 14.036,10.328 12.475,11.889L9.646,14.718C8.085,16.279 5.551,16.279 3.99,14.718L3.282,14.01C1.721,12.449 1.721,9.915 3.282,8.354L6.067,5.569C5.835,6.297 5.793,7.072 5.94,7.817L4.697,9.061C3.526,10.231 3.526,12.133 4.697,13.303C5.867,14.474 7.769,14.474 8.939,13.303L11.061,11.182C12.231,10.011 12.231,8.11 11.061,6.939C10.419,6.297 9.557,6.007 8.717,6.069C8.838,5.742 9.03,5.435 9.293,5.172L9.975,4.49Z") + .namespace("http://www.w3.org/2000/svg") + .viewBox("0 0 20 16") } - .namespace("http://www.w3.org/2000/svg") - .viewBox("0 0 20 16") + .type(.button) + .title("Italic") + .class("toolbar-tool") + .custom(key: "data-command", value: "italic") } - .type(.button) - .title("Link") - .class("toolbar-tool") - .custom(key: "data-command", value: "link") - } - ListItem { - HTMLKit.Button { - Vector { - Path { - Title { - "Code emphasis command" + ListItem { + HTMLKit.Button { + Vector { + Path { + Title { + "Strikethrough emphasis command" + } } + .draw("M6.068,7C5.894,6.829 5.745,6.646 5.621,6.45C5.305,5.95 5.148,5.39 5.148,4.771C5.148,4.09 5.341,3.454 5.727,2.862C6.113,2.27 6.678,1.821 7.42,1.514C8.162,1.208 8.987,1.054 9.894,1.054C10.894,1.054 11.775,1.215 12.539,1.537C13.302,1.859 13.89,2.333 14.301,2.959C14.711,3.584 14.932,4.292 14.963,5.083L13.252,5.212C13.16,4.36 12.849,3.716 12.318,3.28C11.788,2.845 11.004,2.627 9.968,2.627C8.888,2.627 8.102,2.825 7.608,3.221C7.115,3.616 6.868,4.093 6.868,4.651C6.868,5.136 7.043,5.534 7.392,5.847C7.736,6.16 8.632,6.48 10.083,6.808C10.373,6.874 10.644,6.938 10.898,7L6.068,7ZM14.776,9C14.787,9.014 14.797,9.029 14.806,9.044C15.181,9.599 15.368,10.238 15.368,10.962C15.368,11.679 15.162,12.355 14.751,12.99C14.34,13.625 13.75,14.118 12.98,14.471C12.211,14.824 11.345,15 10.382,15C9.161,15 8.139,14.822 7.314,14.466C6.489,14.111 5.842,13.576 5.373,12.861C4.904,12.147 4.657,11.339 4.632,10.437L6.316,10.29C6.396,10.965 6.581,11.518 6.872,11.951C7.164,12.383 7.616,12.732 8.229,12.999C8.842,13.266 9.532,13.399 10.299,13.399C10.98,13.399 11.581,13.298 12.102,13.096C12.623,12.893 13.011,12.616 13.266,12.263C13.52,11.911 13.647,11.526 13.647,11.109C13.647,10.686 13.525,10.316 13.279,10C13.034,9.685 12.629,9.419 12.065,9.205C11.922,9.149 11.709,9.081 11.428,9L14.776,9ZM17,7.277L17,8.777L3,8.777L3,7.277L17,7.277Z") } - .draw("M11.829,2.171C11.57,1.848 11.623,1.376 11.946,1.117C12.269,0.859 12.741,0.911 13,1.234L17.546,7.532C17.765,7.805 17.765,8.195 17.546,8.469L13.171,14.883C12.913,15.206 12.44,15.259 12.117,15C11.794,14.741 11.741,14.269 12,13.946C12,13.946 16,8 16,8L11.829,2.171ZM8.288,13.946C8.547,14.269 8.495,14.741 8.171,15C7.848,15.259 7.376,15.206 7.117,14.883L2.454,8.469C2.235,8.195 2.235,7.805 2.454,7.532L6.946,1.351C7.204,1.028 7.677,0.976 8,1.234C8.323,1.493 8.376,1.965 8.117,2.288C8.117,2.288 4,8 4,8L8.288,13.946Z") + .namespace("http://www.w3.org/2000/svg") + .viewBox("0 0 20 16") } - .namespace("http://www.w3.org/2000/svg") - .viewBox("0 0 20 16") + .type(.button) + .title("Strikethrough") + .class("toolbar-tool") + .custom(key: "data-command", value: "strikethrough") } - .type(.button) - .title("Code") - .class("toolbar-tool") - .custom(key: "data-command", value: "code") - } - ListItem { - HTMLKit.Button { - Vector { - Path { - Title { - "Undo command" + ListItem { + HTMLKit.Button { + Vector { + Path { + Title { + "Link reference command" + } } + .draw("M10.025,11.51C9.368,11.335 8.747,10.99 8.232,10.475L7.525,9.768C5.964,8.207 5.964,5.672 7.525,4.111L10.354,1.282C11.915,-0.279 14.449,-0.279 16.01,1.282L16.718,1.99C18.279,3.551 18.279,6.085 16.718,7.646L13.933,10.431C14.165,9.703 14.207,8.928 14.06,8.183L15.303,6.939C16.474,5.769 16.474,3.867 15.303,2.697C14.133,1.526 12.231,1.526 11.061,2.697L8.939,4.818C7.769,5.989 7.769,7.89 8.939,9.061C9.581,9.703 10.443,9.993 11.283,9.931C11.162,10.258 10.97,10.565 10.707,10.828L10.025,11.51ZM9.975,4.49C10.632,4.665 11.253,5.01 11.768,5.525L12.475,6.232C14.036,7.793 14.036,10.328 12.475,11.889L9.646,14.718C8.085,16.279 5.551,16.279 3.99,14.718L3.282,14.01C1.721,12.449 1.721,9.915 3.282,8.354L6.067,5.569C5.835,6.297 5.793,7.072 5.94,7.817L4.697,9.061C3.526,10.231 3.526,12.133 4.697,13.303C5.867,14.474 7.769,14.474 8.939,13.303L11.061,11.182C12.231,10.011 12.231,8.11 11.061,6.939C10.419,6.297 9.557,6.007 8.717,6.069C8.838,5.742 9.03,5.435 9.293,5.172L9.975,4.49Z") } - .draw("M5.825,6.444L9.783,9.009C10.13,9.234 10.23,9.699 10.004,10.046C9.779,10.394 9.314,10.493 8.967,10.268L2.967,6.379C2.755,6.242 2.627,6.007 2.625,5.755C2.623,5.502 2.749,5.266 2.959,5.126L8.959,1.126C9.303,0.896 9.769,0.99 9.999,1.334C10.229,1.678 10.135,2.144 9.791,2.374L5.936,4.944L12.375,4.944C15.135,4.944 17.375,7.185 17.375,9.944C17.375,12.704 15.135,14.944 12.375,14.944L10.142,14.944C9.939,14.944 9.743,14.863 9.6,14.719C9.456,14.576 9.375,14.38 9.375,14.177C9.375,13.982 9.452,13.796 9.589,13.659C9.727,13.521 9.913,13.444 10.107,13.444L12.375,13.444C14.307,13.444 15.875,11.876 15.875,9.944C15.875,8.012 14.307,6.444 12.375,6.444L5.825,6.444Z") + .namespace("http://www.w3.org/2000/svg") + .viewBox("0 0 20 16") } - .namespace("http://www.w3.org/2000/svg") - .viewBox("0 0 20 16") + .type(.button) + .title("Link") + .class("toolbar-tool") + .custom(key: "data-command", value: "link") + } + ListItem { + HTMLKit.Button { + Vector { + Path { + Title { + "Code emphasis command" + } + } + .draw("M11.829,2.171C11.57,1.848 11.623,1.376 11.946,1.117C12.269,0.859 12.741,0.911 13,1.234L17.546,7.532C17.765,7.805 17.765,8.195 17.546,8.469L13.171,14.883C12.913,15.206 12.44,15.259 12.117,15C11.794,14.741 11.741,14.269 12,13.946C12,13.946 16,8 16,8L11.829,2.171ZM8.288,13.946C8.547,14.269 8.495,14.741 8.171,15C7.848,15.259 7.376,15.206 7.117,14.883L2.454,8.469C2.235,8.195 2.235,7.805 2.454,7.532L6.946,1.351C7.204,1.028 7.677,0.976 8,1.234C8.323,1.493 8.376,1.965 8.117,2.288C8.117,2.288 4,8 4,8L8.288,13.946Z") + } + .namespace("http://www.w3.org/2000/svg") + .viewBox("0 0 20 16") + } + .type(.button) + .title("Code") + .class("toolbar-tool") + .custom(key: "data-command", value: "code") } - .type(.button) - .title("Undo") - .class("toolbar-tool") - .custom(key: "data-command", value: "undo") } - ListItem { - HTMLKit.Button { - Vector { - Path { - Title { - "Redo command" + .class("textpad-action") + Menu { + ListItem { + HTMLKit.Button { + Vector { + Path { + Title { + "Undo command" + } } + .draw("M5.825,6.444L9.783,9.009C10.13,9.234 10.23,9.699 10.004,10.046C9.779,10.394 9.314,10.493 8.967,10.268L2.967,6.379C2.755,6.242 2.627,6.007 2.625,5.755C2.623,5.502 2.749,5.266 2.959,5.126L8.959,1.126C9.303,0.896 9.769,0.99 9.999,1.334C10.229,1.678 10.135,2.144 9.791,2.374L5.936,4.944L12.375,4.944C15.135,4.944 17.375,7.185 17.375,9.944C17.375,12.704 15.135,14.944 12.375,14.944L10.142,14.944C9.939,14.944 9.743,14.863 9.6,14.719C9.456,14.576 9.375,14.38 9.375,14.177C9.375,13.982 9.452,13.796 9.589,13.659C9.727,13.521 9.913,13.444 10.107,13.444L12.375,13.444C14.307,13.444 15.875,11.876 15.875,9.944C15.875,8.012 14.307,6.444 12.375,6.444L5.825,6.444Z") } - .draw("M14.175,6.444L10.217,9.009C9.87,9.234 9.77,9.699 9.996,10.046C10.221,10.394 10.686,10.493 11.033,10.268L17.033,6.379C17.245,6.242 17.373,6.007 17.375,5.755C17.377,5.502 17.251,5.266 17.041,5.126L11.041,1.126C10.697,0.896 10.231,0.99 10.001,1.334C9.771,1.678 9.865,2.144 10.209,2.374L14.064,4.944L7.625,4.944C4.865,4.944 2.625,7.185 2.625,9.944C2.625,12.704 4.865,14.944 7.625,14.944L9.858,14.944C10.061,14.944 10.257,14.863 10.4,14.719C10.544,14.576 10.625,14.38 10.625,14.177C10.625,13.982 10.548,13.796 10.411,13.659C10.273,13.521 10.087,13.444 9.893,13.444L7.625,13.444C5.693,13.444 4.125,11.876 4.125,9.944C4.125,8.012 5.693,6.444 7.625,6.444L14.175,6.444Z") + .namespace("http://www.w3.org/2000/svg") + .viewBox("0 0 20 16") } - .namespace("http://www.w3.org/2000/svg") - .viewBox("0 0 20 16") + .type(.button) + .title("Undo") + .class("toolbar-tool") + .custom(key: "data-command", value: "undo") + } + ListItem { + HTMLKit.Button { + Vector { + Path { + Title { + "Redo command" + } + } + .draw("M14.175,6.444L10.217,9.009C9.87,9.234 9.77,9.699 9.996,10.046C10.221,10.394 10.686,10.493 11.033,10.268L17.033,6.379C17.245,6.242 17.373,6.007 17.375,5.755C17.377,5.502 17.251,5.266 17.041,5.126L11.041,1.126C10.697,0.896 10.231,0.99 10.001,1.334C9.771,1.678 9.865,2.144 10.209,2.374L14.064,4.944L7.625,4.944C4.865,4.944 2.625,7.185 2.625,9.944C2.625,12.704 4.865,14.944 7.625,14.944L9.858,14.944C10.061,14.944 10.257,14.863 10.4,14.719C10.544,14.576 10.625,14.38 10.625,14.177C10.625,13.982 10.548,13.796 10.411,13.659C10.273,13.521 10.087,13.444 9.893,13.444L7.625,13.444C5.693,13.444 4.125,11.876 4.125,9.944C4.125,8.012 5.693,6.444 7.625,6.444L14.175,6.444Z") + } + .namespace("http://www.w3.org/2000/svg") + .viewBox("0 0 20 16") + } + .type(.button) + .title("Redo") + .class("toolbar-tool") + .custom(key: "data-command", value: "redo") } - .type(.button) - .title("Redo") - .class("toolbar-tool") - .custom(key: "data-command", value: "redo") } + .class("textpad-revision") } .class("textpad-toolbar") TextArea { diff --git a/Sources/HTMLKitComponents/Resources/css/forms/textpad.css b/Sources/HTMLKitComponents/Resources/css/forms/textpad.css index 3abf6bb9..9df0b568 100644 --- a/Sources/HTMLKitComponents/Resources/css/forms/textpad.css +++ b/Sources/HTMLKitComponents/Resources/css/forms/textpad.css @@ -59,7 +59,7 @@ --borderColor: var(--redColor); } -.textpad:has(.textpad-content:focus-within) .toolbar-tool { +.textpad:has(.textpad-content:focus-within) .textpad-action .toolbar-tool { color: hsla(var(--foregroundColor), 1.0); } @@ -67,18 +67,116 @@ display: flex; flex-direction: row; align-items: center; - justify-content: flex-start; + justify-content: space-between; padding-block-start: var(--paddingBlockStart); padding-block-end: var(--paddingBlockEnd); padding-inline-start: var(--paddingInlineStart); padding-inline-end: var(--paddingInlineEnd); +} + +.toolbar-context { + position: relative; + display: inline-block; +} + +@media (min-width: 768px) { + .toolbar-context { + display: none; + } +} + +.toolbar-context summary { + list-style: none; + cursor: pointer; +} + +.toolbar-context summary::-webkit-details-marker { + display: none; +} + +.toolbar-context summary svg { + display: inline-block; + inline-size: 1.25em; + block-size: 1.0em; + fill: currentColor; + font-size: 1.0rem; + line-height: 1.5; + vertical-align: middle; + pointer-events: none; +} + +.toolbar-context ul { + position: absolute; + z-index: 1; + margin-block: 0.5rem; + padding-block: 0.5rem; + padding-inline: 0.5rem; + display: flex; + flex-direction: row; + align-items: center; + inline-size: max-content; + border-width: var(--borderWidth); + border-style: solid; + border-color: hsla(var(--systemBorderColor), 1.0); + border-radius: var(--borderRadius); + background-color: hsla(var(--backgroundColor), var(--backgroundOpacity)); + list-style: none; +} + +.toolbar-context ul li { + position: relative; +} + +.toolbar-context ul li .toolbar-tool { + color: hsla(var(--foregroundColor), 1.0); +} + +.textpad-action { + display: none; + flex-direction: row; + align-items: center; + justify-content: flex-start; + gap: 0.75rem; + list-style: none; + margin: unset !important; +} + +@media (min-width: 768px) { + .textpad-action { + display: flex; + } +} + +.textpad-action > li { + position: relative; +} + +.textpad-revision { + display: flex; + flex-direction: row; + align-items: center; + justify-content: flex-start; + gap: 0.75rem; list-style: none; margin: unset !important; } +.textpad-revision > li { + position: relative; +} + +.textpad-revision .toolbar-tool { + color: hsla(var(--foregroundColor), 1.0); +} + +.textpad-revision .toolbar-tool.state\:disabled { + color: hsla(var(--foregroundColor), 0.5); +} + .toolbar-tool { display: inline-block; - padding: 0.375rem 0.75rem; + inline-size: 32px; + block-size: 32px; color: hsla(var(--foregroundColor), 0.5); cursor: pointer; -webkit-user-select: none; @@ -89,8 +187,12 @@ background-color: unset; } +.toolbar-tool > * { + pointer-events: none; +} + .toolbar-tool:hover { - background-color: hsla(var(--systemTextColor), 0.1); + background-color: hsla(var(--systemBorderColor), 0.5); } .toolbar-tool > svg { diff --git a/Sources/HTMLKitComponents/Resources/js/components/forms/textpad.js b/Sources/HTMLKitComponents/Resources/js/components/forms/textpad.js index 9cc28419..a72c8a5c 100644 --- a/Sources/HTMLKitComponents/Resources/js/components/forms/textpad.js +++ b/Sources/HTMLKitComponents/Resources/js/components/forms/textpad.js @@ -9,8 +9,10 @@ this.element = element; this.history = []; + this.context = element.getElementsByClassName('toolbar-context')[0]; this.content = element.getElementsByClassName('textpad-content')[0]; - this.toolbar = element.getElementsByClassName('textpad-toolbar')[0]; + this.action = element.getElementsByClassName('textpad-action')[0]; + this.revision = element.getElementsByClassName('textpad-revision')[0]; this.initiateListener(); @@ -29,24 +31,57 @@ self.index = self.writeHistory(self.content.value); }); + this.revision.addEventListener('click', function(event) { + + if (event.target.tagName === 'BUTTON') { + + const command = event.target.dataset.command; + + self.content.setRangeText(self.revertChange(command), 0, self.content.textLength, 'end'); + } + }); + // Listens to tool selection - this.toolbar.addEventListener('click', function (event) { + this.action.addEventListener('click', function (event) { + + if (event.target.tagName === 'BUTTON') { - event.preventDefault(); + const command = event.target.dataset.command; + + self.content.setRangeText(self.replaceSelection(command), self.content.selectionStart, self.content.selectionEnd); + + // Write history, since the listener does not act on text replacements + self.index = self.writeHistory(self.content.value); + } + }); + + // Listens to tool selection + this.context.addEventListener('click', function (event) { if (event.target.tagName === 'BUTTON') { const command = event.target.dataset.command; - if (command === 'undo' || command === 'redo') { - self.content.setRangeText(self.revertChange(command), 0, self.content.textLength, 'end'); + self.content.setRangeText(self.replaceSelection(command), self.content.selectionStart, self.content.selectionEnd); + + // Write history, since the listener does not act on text replacements + self.index = self.writeHistory(self.content.value); + } + }); + + // Dismisses the context menu, when the escape key as pushed + window.addEventListener('keyup', function (event) { + + if(event.key === 'Escape') { + self.context.removeAttribute('open'); + } + }); - } else { - self.content.setRangeText(self.replaceSelection(command), self.content.selectionStart, self.content.selectionEnd); + // Dismisses the context menu, when it loses its focus + window.addEventListener('click', function (event) { - // Write history, since the listener does not act on text replacements - self.index = self.writeHistory(self.content.value); - } + if (!self.context.contains(event.target)) { + self.context.removeAttribute('open'); } }); }; From 11b62c1708b5ade22610c235f56fc0460ee07000 Mon Sep 17 00:00:00 2001 From: Mattes Mohr Date: Sat, 3 Aug 2024 11:24:17 +0200 Subject: [PATCH 2/3] Add a tooltip to each toolbar control --- .../HTMLKitComponents/Components/Form.swift | 71 +++++++++++++++---- .../Resources/css/forms/textpad.css | 19 +++++ 2 files changed, 75 insertions(+), 15 deletions(-) diff --git a/Sources/HTMLKitComponents/Components/Form.swift b/Sources/HTMLKitComponents/Components/Form.swift index 98b65314..00c202e3 100644 --- a/Sources/HTMLKitComponents/Components/Form.swift +++ b/Sources/HTMLKitComponents/Components/Form.swift @@ -1428,6 +1428,10 @@ public struct TextPad: View, Modifiable, Identifiable { .type(.button) .class("toolbar-tool") .custom(key: "data-command", value: "bold") + Span { + "Bold" + } + .class("tooltip") } ListItem { HTMLKit.Button { @@ -1445,6 +1449,10 @@ public struct TextPad: View, Modifiable, Identifiable { .type(.button) .class("toolbar-tool") .custom(key: "data-command", value: "italic") + Span { + "Italic" + } + .class("tooltip") } ListItem { HTMLKit.Button { @@ -1462,6 +1470,10 @@ public struct TextPad: View, Modifiable, Identifiable { .type(.button) .class("toolbar-tool") .custom(key: "data-command", value: "strikethrough") + Span { + "Strikethrough" + } + .class("tooltip") } ListItem { HTMLKit.Button { @@ -1479,13 +1491,17 @@ public struct TextPad: View, Modifiable, Identifiable { .type(.button) .class("toolbar-tool") .custom(key: "data-command", value: "link") + Span { + "Link" + } + .class("tooltip") } ListItem { HTMLKit.Button { Vector { Path { Title { - "Code emphasis command" + "Code" } } .draw("M11.829,2.171C11.57,1.848 11.623,1.376 11.946,1.117C12.269,0.859 12.741,0.911 13,1.234L17.546,7.532C17.765,7.805 17.765,8.195 17.546,8.469L13.171,14.883C12.913,15.206 12.44,15.259 12.117,15C11.794,14.741 11.741,14.269 12,13.946C12,13.946 16,8 16,8L11.829,2.171ZM8.288,13.946C8.547,14.269 8.495,14.741 8.171,15C7.848,15.259 7.376,15.206 7.117,14.883L2.454,8.469C2.235,8.195 2.235,7.805 2.454,7.532L6.946,1.351C7.204,1.028 7.677,0.976 8,1.234C8.323,1.493 8.376,1.965 8.117,2.288C8.117,2.288 4,8 4,8L8.288,13.946Z") @@ -1496,6 +1512,10 @@ public struct TextPad: View, Modifiable, Identifiable { .type(.button) .class("toolbar-tool") .custom(key: "data-command", value: "code") + Span { + "Code" + } + .class("tooltip") } } } @@ -1506,7 +1526,7 @@ public struct TextPad: View, Modifiable, Identifiable { Vector { Path { Title { - "Bold emphasis command" + "Bold" } } .draw("M4.25,14.25L4.25,1.75C4.25,1.336 4.586,1 5,1L10.769,1C12.646,1 14.212,2.659 14.212,4.75C14.212,5.686 13.898,6.785 13.383,7.438C14.746,7.929 15.75,9.576 15.75,11.25C15.75,13.341 14.184,15 12.308,15L5,15C4.586,15 4.25,14.664 4.25,14.25ZM10.769,2.5L5.75,2.5C5.75,2.5 5.75,7.25 5.75,7.25L10.769,7.25C11.865,7.25 12.712,5.971 12.712,4.75C12.712,3.529 11.865,2.5 10.769,2.5ZM14.25,11.25C14.25,10.029 13.403,8.75 12.308,8.75L5.75,8.75C5.75,8.75 5.75,13.5 5.75,13.5L12.308,13.5C13.403,13.5 14.25,12.471 14.25,11.25Z") @@ -1515,16 +1535,19 @@ public struct TextPad: View, Modifiable, Identifiable { .viewBox("0 0 20 16") } .type(.button) - .title("Bold") .class("toolbar-tool") .custom(key: "data-command", value: "bold") + Span { + "Bold" + } + .class("tooltip") } ListItem { HTMLKit.Button { Vector { Path { Title { - "Italic emphasis command" + "Italic" } } .draw("M8.989,15L4,15C3.586,15 3.25,14.664 3.25,14.25C3.25,13.836 3.586,13.5 4,13.5L8.36,13.5L10.12,2.5L6,2.5C5.586,2.5 5.25,2.164 5.25,1.75C5.25,1.336 5.586,1 6,1C6,1 11.003,1 11.011,1L16,1C16.414,1 16.75,1.336 16.75,1.75C16.75,2.164 16.414,2.5 16,2.5L11.64,2.5L9.88,13.5L14,13.5C14.414,13.5 14.75,13.836 14.75,14.25C14.75,14.664 14.414,15 14,15C14,15 8.997,15 8.989,15Z") @@ -1533,16 +1556,19 @@ public struct TextPad: View, Modifiable, Identifiable { .viewBox("0 0 20 16") } .type(.button) - .title("Italic") .class("toolbar-tool") .custom(key: "data-command", value: "italic") + Span { + "Italic" + } + .class("tooltip") } ListItem { HTMLKit.Button { Vector { Path { Title { - "Strikethrough emphasis command" + "Strikethrough" } } .draw("M6.068,7C5.894,6.829 5.745,6.646 5.621,6.45C5.305,5.95 5.148,5.39 5.148,4.771C5.148,4.09 5.341,3.454 5.727,2.862C6.113,2.27 6.678,1.821 7.42,1.514C8.162,1.208 8.987,1.054 9.894,1.054C10.894,1.054 11.775,1.215 12.539,1.537C13.302,1.859 13.89,2.333 14.301,2.959C14.711,3.584 14.932,4.292 14.963,5.083L13.252,5.212C13.16,4.36 12.849,3.716 12.318,3.28C11.788,2.845 11.004,2.627 9.968,2.627C8.888,2.627 8.102,2.825 7.608,3.221C7.115,3.616 6.868,4.093 6.868,4.651C6.868,5.136 7.043,5.534 7.392,5.847C7.736,6.16 8.632,6.48 10.083,6.808C10.373,6.874 10.644,6.938 10.898,7L6.068,7ZM14.776,9C14.787,9.014 14.797,9.029 14.806,9.044C15.181,9.599 15.368,10.238 15.368,10.962C15.368,11.679 15.162,12.355 14.751,12.99C14.34,13.625 13.75,14.118 12.98,14.471C12.211,14.824 11.345,15 10.382,15C9.161,15 8.139,14.822 7.314,14.466C6.489,14.111 5.842,13.576 5.373,12.861C4.904,12.147 4.657,11.339 4.632,10.437L6.316,10.29C6.396,10.965 6.581,11.518 6.872,11.951C7.164,12.383 7.616,12.732 8.229,12.999C8.842,13.266 9.532,13.399 10.299,13.399C10.98,13.399 11.581,13.298 12.102,13.096C12.623,12.893 13.011,12.616 13.266,12.263C13.52,11.911 13.647,11.526 13.647,11.109C13.647,10.686 13.525,10.316 13.279,10C13.034,9.685 12.629,9.419 12.065,9.205C11.922,9.149 11.709,9.081 11.428,9L14.776,9ZM17,7.277L17,8.777L3,8.777L3,7.277L17,7.277Z") @@ -1551,16 +1577,19 @@ public struct TextPad: View, Modifiable, Identifiable { .viewBox("0 0 20 16") } .type(.button) - .title("Strikethrough") .class("toolbar-tool") .custom(key: "data-command", value: "strikethrough") + Span { + "Strikethrough" + } + .class("tooltip") } ListItem { HTMLKit.Button { Vector { Path { Title { - "Link reference command" + "Link" } } .draw("M10.025,11.51C9.368,11.335 8.747,10.99 8.232,10.475L7.525,9.768C5.964,8.207 5.964,5.672 7.525,4.111L10.354,1.282C11.915,-0.279 14.449,-0.279 16.01,1.282L16.718,1.99C18.279,3.551 18.279,6.085 16.718,7.646L13.933,10.431C14.165,9.703 14.207,8.928 14.06,8.183L15.303,6.939C16.474,5.769 16.474,3.867 15.303,2.697C14.133,1.526 12.231,1.526 11.061,2.697L8.939,4.818C7.769,5.989 7.769,7.89 8.939,9.061C9.581,9.703 10.443,9.993 11.283,9.931C11.162,10.258 10.97,10.565 10.707,10.828L10.025,11.51ZM9.975,4.49C10.632,4.665 11.253,5.01 11.768,5.525L12.475,6.232C14.036,7.793 14.036,10.328 12.475,11.889L9.646,14.718C8.085,16.279 5.551,16.279 3.99,14.718L3.282,14.01C1.721,12.449 1.721,9.915 3.282,8.354L6.067,5.569C5.835,6.297 5.793,7.072 5.94,7.817L4.697,9.061C3.526,10.231 3.526,12.133 4.697,13.303C5.867,14.474 7.769,14.474 8.939,13.303L11.061,11.182C12.231,10.011 12.231,8.11 11.061,6.939C10.419,6.297 9.557,6.007 8.717,6.069C8.838,5.742 9.03,5.435 9.293,5.172L9.975,4.49Z") @@ -1569,16 +1598,19 @@ public struct TextPad: View, Modifiable, Identifiable { .viewBox("0 0 20 16") } .type(.button) - .title("Link") .class("toolbar-tool") .custom(key: "data-command", value: "link") + Span { + "Link" + } + .class("tooltip") } ListItem { HTMLKit.Button { Vector { Path { Title { - "Code emphasis command" + "Code" } } .draw("M11.829,2.171C11.57,1.848 11.623,1.376 11.946,1.117C12.269,0.859 12.741,0.911 13,1.234L17.546,7.532C17.765,7.805 17.765,8.195 17.546,8.469L13.171,14.883C12.913,15.206 12.44,15.259 12.117,15C11.794,14.741 11.741,14.269 12,13.946C12,13.946 16,8 16,8L11.829,2.171ZM8.288,13.946C8.547,14.269 8.495,14.741 8.171,15C7.848,15.259 7.376,15.206 7.117,14.883L2.454,8.469C2.235,8.195 2.235,7.805 2.454,7.532L6.946,1.351C7.204,1.028 7.677,0.976 8,1.234C8.323,1.493 8.376,1.965 8.117,2.288C8.117,2.288 4,8 4,8L8.288,13.946Z") @@ -1587,9 +1619,12 @@ public struct TextPad: View, Modifiable, Identifiable { .viewBox("0 0 20 16") } .type(.button) - .title("Code") .class("toolbar-tool") .custom(key: "data-command", value: "code") + Span { + "Code" + } + .class("tooltip") } } .class("textpad-action") @@ -1599,7 +1634,7 @@ public struct TextPad: View, Modifiable, Identifiable { Vector { Path { Title { - "Undo command" + "Undo" } } .draw("M5.825,6.444L9.783,9.009C10.13,9.234 10.23,9.699 10.004,10.046C9.779,10.394 9.314,10.493 8.967,10.268L2.967,6.379C2.755,6.242 2.627,6.007 2.625,5.755C2.623,5.502 2.749,5.266 2.959,5.126L8.959,1.126C9.303,0.896 9.769,0.99 9.999,1.334C10.229,1.678 10.135,2.144 9.791,2.374L5.936,4.944L12.375,4.944C15.135,4.944 17.375,7.185 17.375,9.944C17.375,12.704 15.135,14.944 12.375,14.944L10.142,14.944C9.939,14.944 9.743,14.863 9.6,14.719C9.456,14.576 9.375,14.38 9.375,14.177C9.375,13.982 9.452,13.796 9.589,13.659C9.727,13.521 9.913,13.444 10.107,13.444L12.375,13.444C14.307,13.444 15.875,11.876 15.875,9.944C15.875,8.012 14.307,6.444 12.375,6.444L5.825,6.444Z") @@ -1608,16 +1643,19 @@ public struct TextPad: View, Modifiable, Identifiable { .viewBox("0 0 20 16") } .type(.button) - .title("Undo") .class("toolbar-tool") .custom(key: "data-command", value: "undo") + Span { + "Undo" + } + .class("tooltip") } ListItem { HTMLKit.Button { Vector { Path { Title { - "Redo command" + "Redo" } } .draw("M14.175,6.444L10.217,9.009C9.87,9.234 9.77,9.699 9.996,10.046C10.221,10.394 10.686,10.493 11.033,10.268L17.033,6.379C17.245,6.242 17.373,6.007 17.375,5.755C17.377,5.502 17.251,5.266 17.041,5.126L11.041,1.126C10.697,0.896 10.231,0.99 10.001,1.334C9.771,1.678 9.865,2.144 10.209,2.374L14.064,4.944L7.625,4.944C4.865,4.944 2.625,7.185 2.625,9.944C2.625,12.704 4.865,14.944 7.625,14.944L9.858,14.944C10.061,14.944 10.257,14.863 10.4,14.719C10.544,14.576 10.625,14.38 10.625,14.177C10.625,13.982 10.548,13.796 10.411,13.659C10.273,13.521 10.087,13.444 9.893,13.444L7.625,13.444C5.693,13.444 4.125,11.876 4.125,9.944C4.125,8.012 5.693,6.444 7.625,6.444L14.175,6.444Z") @@ -1626,9 +1664,12 @@ public struct TextPad: View, Modifiable, Identifiable { .viewBox("0 0 20 16") } .type(.button) - .title("Redo") .class("toolbar-tool") .custom(key: "data-command", value: "redo") + Span { + "Redo" + } + .class("tooltip") } } .class("textpad-revision") diff --git a/Sources/HTMLKitComponents/Resources/css/forms/textpad.css b/Sources/HTMLKitComponents/Resources/css/forms/textpad.css index 9df0b568..1d386bdc 100644 --- a/Sources/HTMLKitComponents/Resources/css/forms/textpad.css +++ b/Sources/HTMLKitComponents/Resources/css/forms/textpad.css @@ -173,6 +173,21 @@ color: hsla(var(--foregroundColor), 0.5); } +.tooltip { + position: absolute; + top: 100%; + z-index: 1; + padding-inline: 0.313rem; + padding-block: 0.625rem; + display: none; + inline-size: max-content; + font-size: 14px; + text-align: center; + color: hsla(var(--whiteColor), 1.0); + border-radius: var(--borderRadius); + background-color: hsla(var(--blackColor), 1.0); +} + .toolbar-tool { display: inline-block; inline-size: 32px; @@ -195,6 +210,10 @@ background-color: hsla(var(--systemBorderColor), 0.5); } +.toolbar-tool:hover + .tooltip { + display: block; +} + .toolbar-tool > svg { display: inline-block; inline-size: 1.25em; From 4f254808ee688b447b61606db2de33dfd4bd4001 Mon Sep 17 00:00:00 2001 From: Mattes Mohr Date: Sun, 4 Aug 2024 21:30:04 +0200 Subject: [PATCH 3/3] Enable the revision tools only when a text change has happend --- .../HTMLKitComponents/Components/Form.swift | 4 +- .../Resources/js/components/forms/textpad.js | 37 +++++++++++++++++++ 2 files changed, 39 insertions(+), 2 deletions(-) diff --git a/Sources/HTMLKitComponents/Components/Form.swift b/Sources/HTMLKitComponents/Components/Form.swift index 00c202e3..d59ffeb7 100644 --- a/Sources/HTMLKitComponents/Components/Form.swift +++ b/Sources/HTMLKitComponents/Components/Form.swift @@ -1643,7 +1643,7 @@ public struct TextPad: View, Modifiable, Identifiable { .viewBox("0 0 20 16") } .type(.button) - .class("toolbar-tool") + .class("toolbar-tool state:disabled") .custom(key: "data-command", value: "undo") Span { "Undo" @@ -1664,7 +1664,7 @@ public struct TextPad: View, Modifiable, Identifiable { .viewBox("0 0 20 16") } .type(.button) - .class("toolbar-tool") + .class("toolbar-tool state:disabled") .custom(key: "data-command", value: "redo") Span { "Redo" diff --git a/Sources/HTMLKitComponents/Resources/js/components/forms/textpad.js b/Sources/HTMLKitComponents/Resources/js/components/forms/textpad.js index a72c8a5c..b60b7607 100644 --- a/Sources/HTMLKitComponents/Resources/js/components/forms/textpad.js +++ b/Sources/HTMLKitComponents/Resources/js/components/forms/textpad.js @@ -26,9 +26,17 @@ const self = this; + const undo = this.revision.getElementsByClassName('toolbar-tool')[0]; + // Listens to text changes this.content.addEventListener('input', function (event) { + self.index = self.writeHistory(self.content.value); + + if (self.index >= 1) { + undo.classList.remove('state:disabled'); + } + }); this.revision.addEventListener('click', function(event) { @@ -38,6 +46,8 @@ const command = event.target.dataset.command; self.content.setRangeText(self.revertChange(command), 0, self.content.textLength, 'end'); + + self.checkRevision(); } }); @@ -52,6 +62,8 @@ // Write history, since the listener does not act on text replacements self.index = self.writeHistory(self.content.value); + + self.checkRevision(); } }); @@ -66,6 +78,8 @@ // Write history, since the listener does not act on text replacements self.index = self.writeHistory(self.content.value); + + self.checkRevision(); } }); @@ -86,6 +100,29 @@ }); }; + /** + * Checks the revision state. + */ + Textpad.prototype.checkRevision = function () { + + const undo = this.revision.getElementsByClassName('toolbar-tool')[0]; + const redo = this.revision.getElementsByClassName('toolbar-tool')[1]; + + if (this.index >= 1) { + undo.classList.remove('state:disabled'); + + } else { + undo.classList.add('state:disabled'); + } + + if (this.index < (this.history.length - 1)) { + redo.classList.remove('state:disabled'); + + } else { + redo.classList.add('state:disabled'); + } + }; + /** * Reverts the latest text change. */