deprecated
1 week ago
block.json
1 week ago
component.js
1 week ago
edit.js
1 week ago
icon.svg
2 months ago
index.js
1 week ago
index.php
2 months ago
save.js
1 week ago
style.scss
1 week ago
transforms.js
2 months ago
component.js
208 lines
| 1 | import { Component } from '@wordpress/element'; |
| 2 | import parse from 'html-react-parser'; |
| 3 | import { isHexColor } from '@vkblocks/utils/is-hex-color'; |
| 4 | import { sanitizeSlug } from '@vkblocks/utils/sanitizeSlug'; |
| 5 | import { fixBrokenUnicode } from '@vkblocks/utils/fixBrokenUnicode'; |
| 6 | |
| 7 | export class VKBButton extends Component { |
| 8 | render() { |
| 9 | const buttonTextColorCustom = this.props.lbTextColorCustom; |
| 10 | const buttonColorCustom = this.props.lbColorCustom; |
| 11 | const buttonColor = this.props.lbColor; |
| 12 | const buttonType = this.props.lbType; |
| 13 | const buttonAlign = this.props.lbAlign; |
| 14 | const buttonSize = this.props.lbSize; |
| 15 | const buttonUrl = this.props.lbUrl; |
| 16 | const buttonTarget = this.props.lbTarget; |
| 17 | const relAttribute = this.props.lbRelAttribute; |
| 18 | const linkToPost = this.props.lbLinkToPost; |
| 19 | let fontAwesomeIconBefore = this.props.lbFontAwesomeIconBefore; |
| 20 | let fontAwesomeIconAfter = this.props.lbFontAwesomeIconAfter; |
| 21 | if (fontAwesomeIconBefore) { |
| 22 | fontAwesomeIconBefore = fixBrokenUnicode(fontAwesomeIconBefore); |
| 23 | } |
| 24 | if (fontAwesomeIconAfter) { |
| 25 | fontAwesomeIconAfter = fixBrokenUnicode(fontAwesomeIconAfter); |
| 26 | } |
| 27 | const iconSizeBefore = this.props.lbIconSizeBefore; |
| 28 | const iconSizeAfter = this.props.lbIconSizeAfter; |
| 29 | const richText = this.props.lbRichtext; |
| 30 | const subCaption = this.props.lbsubCaption; |
| 31 | const lbsubCaptionRichText = this.props.lbsubCaptionRichText; |
| 32 | const inlineStyle = this.props.inlineStyle; |
| 33 | const borderRadius = this.props.borderRadius; |
| 34 | // 任意指定の文字サイズ(単位込み CSS 値。例: 18px / 1.2em / 1rem)。 |
| 35 | // 値があるときはサイズプリセット(btn-*)を付けず、インライン font-size で指定する。 |
| 36 | // Optional font size as a CSS value with unit (e.g. 18px / 1.2em / 1rem). |
| 37 | // When set, the size preset (btn-*) is omitted and the font size is applied inline instead. |
| 38 | const fontSizeValue = this.props.lbFontSizeValue; |
| 39 | let aClass = ''; |
| 40 | let iconBefore = ''; |
| 41 | let iconAfter = ''; |
| 42 | |
| 43 | aClass = `vk_button_link`; |
| 44 | |
| 45 | // 塗り |
| 46 | if (buttonType === '0' || buttonType === null) { |
| 47 | // 規定カラーの場合 |
| 48 | if (buttonColor !== 'custom' && buttonColorCustom === undefined) { |
| 49 | aClass += ` btn has-background has-vk-color-${buttonColor}-background-color`; |
| 50 | } else { |
| 51 | aClass += ` btn has-background`; |
| 52 | // カスタムパレットカラーの場合 |
| 53 | if (!isHexColor(buttonColorCustom)) { |
| 54 | aClass += ` has-${sanitizeSlug(buttonColorCustom)}-background-color`; |
| 55 | } |
| 56 | } |
| 57 | |
| 58 | // 文字色 |
| 59 | if ( |
| 60 | buttonColor === 'custom' && |
| 61 | buttonTextColorCustom !== undefined |
| 62 | ) { |
| 63 | aClass += ` btn has-text-color`; |
| 64 | // カスタムパレットカラーの場合 |
| 65 | if (!isHexColor(buttonTextColorCustom)) { |
| 66 | aClass += ` has-${sanitizeSlug(buttonTextColorCustom)}-color`; |
| 67 | } |
| 68 | } |
| 69 | // 塗りなし |
| 70 | } else if (buttonType === '1') { |
| 71 | // 規定カラーの場合 |
| 72 | if (buttonColor !== 'custom' && buttonColorCustom === undefined) { |
| 73 | aClass += ` btn has-text-color is-style-outline has-vk-color-${buttonColor}-color`; |
| 74 | } else { |
| 75 | aClass += ` btn has-text-color is-style-outline`; |
| 76 | // カスタムパレットカラーの場合 |
| 77 | if (!isHexColor(buttonColorCustom)) { |
| 78 | aClass += ` has-${sanitizeSlug(buttonColorCustom)}-color`; |
| 79 | } |
| 80 | } |
| 81 | // テキストのみ |
| 82 | } else if (buttonType === '2') { |
| 83 | // 規定カラーの場合 |
| 84 | if (buttonColor !== 'custom' && buttonColorCustom === undefined) { |
| 85 | aClass += ` has-text-color vk_button_link-type-text has-vk-color-${buttonColor}-color`; |
| 86 | } else { |
| 87 | aClass += ` has-text-color vk_button_link-type-text`; |
| 88 | // カスタムパレットカラーの場合 |
| 89 | if (!isHexColor(buttonColorCustom)) { |
| 90 | aClass += ` has-${sanitizeSlug(buttonColorCustom)}-color`; |
| 91 | } |
| 92 | } |
| 93 | } |
| 94 | |
| 95 | // 文字色がカスタムカラーの場合 |
| 96 | /* |
| 97 | if ( |
| 98 | buttonTextColorCustom !== undefined && |
| 99 | isHexColor(buttonTextColorCustom) && |
| 100 | isSelected |
| 101 | ) { |
| 102 | aStyle = { |
| 103 | // 編集画面対策 |
| 104 | color: `${buttonTextColorCustom}`, |
| 105 | }; |
| 106 | } |
| 107 | */ |
| 108 | |
| 109 | // 任意の文字サイズ(fontSizeValue)が指定されている時は、サイズプリセット(btn-*)を |
| 110 | // 付与しない(プリセットと数値指定を出力レベルで排他にする)。 |
| 111 | // 未指定(=既存データを含む大多数)の時は従来どおり btn-{buttonSize} を付与するため、 |
| 112 | // 既存の保存済み HTML はバイト単位で不変になる。 |
| 113 | // When a font size value is set, do not add the size preset (btn-*) so the preset |
| 114 | // and the numeric size are mutually exclusive at output level. When it is unset |
| 115 | // (including existing data), btn-{buttonSize} is added as before, keeping the |
| 116 | // saved HTML byte-identical for legacy blocks. |
| 117 | if (!fontSizeValue) { |
| 118 | aClass = `${aClass} btn-${buttonSize}`; |
| 119 | } |
| 120 | |
| 121 | if (buttonAlign === 'block') { |
| 122 | aClass = `${aClass} btn-block`; |
| 123 | } |
| 124 | |
| 125 | //過去バージョンをリカバリーした時にiconを正常に表示する |
| 126 | if (fontAwesomeIconBefore && !fontAwesomeIconBefore.match(/<i/)) { |
| 127 | fontAwesomeIconBefore = `<i class="${fontAwesomeIconBefore}"></i>`; |
| 128 | } |
| 129 | if (fontAwesomeIconAfter && !fontAwesomeIconAfter.match(/<i/)) { |
| 130 | fontAwesomeIconAfter = `<i class="${fontAwesomeIconAfter}"></i>`; |
| 131 | } |
| 132 | |
| 133 | if (fontAwesomeIconBefore) { |
| 134 | let fontAwesomeIconBeforeClassName = |
| 135 | fontAwesomeIconBefore.match(/class="(.*?)"/)[1]; |
| 136 | fontAwesomeIconBeforeClassName += ` vk_button_link_before`; |
| 137 | const styleBefore = iconSizeBefore |
| 138 | ? ` style='font-size: ${iconSizeBefore}'` |
| 139 | : ''; |
| 140 | iconBefore = `<i class="${fontAwesomeIconBeforeClassName}"${styleBefore}></i>`; |
| 141 | } |
| 142 | if (fontAwesomeIconAfter) { |
| 143 | let fontAwesomeIconAfterClassName = |
| 144 | fontAwesomeIconAfter.match(/class="(.*?)"/)[1]; |
| 145 | fontAwesomeIconAfterClassName += ` vk_button_link_after`; |
| 146 | const styleAfter = iconSizeAfter |
| 147 | ? ` style='font-size: ${iconSizeAfter}'` |
| 148 | : ''; |
| 149 | iconAfter = `<i class="${fontAwesomeIconAfterClassName}"${styleAfter}></i>`; |
| 150 | } |
| 151 | |
| 152 | // inlineStyleからborderRadius・任意文字サイズを含む新しいスタイルオブジェクトを構築 |
| 153 | const btnInlineStyle = { ...inlineStyle }; |
| 154 | if (borderRadius) { |
| 155 | btnInlineStyle.borderRadius = borderRadius; |
| 156 | } |
| 157 | // 任意の文字サイズが指定されている時だけインライン font-size を出力する。 |
| 158 | // 未指定の時は何も足さないので既存の保存済み HTML は不変。 |
| 159 | // Output an inline font-size only when a font size value is set; nothing is added |
| 160 | // otherwise so the saved HTML stays unchanged for legacy blocks. |
| 161 | if (fontSizeValue) { |
| 162 | btnInlineStyle.fontSize = fontSizeValue; |
| 163 | } |
| 164 | |
| 165 | // rel属性の設定 |
| 166 | let relValue = 'noopener'; |
| 167 | if (relAttribute) { |
| 168 | relValue = relAttribute.includes('noopener') |
| 169 | ? relAttribute |
| 170 | : `${relAttribute} noopener`; |
| 171 | } |
| 172 | |
| 173 | return ( |
| 174 | /* eslint react/jsx-no-target-blank: 0 */ |
| 175 | /* eslint-disable-next-line jsx-a11y/anchor-is-valid -- linkToPost: href replaced server-side with permalink */ |
| 176 | <a |
| 177 | href={linkToPost ? '#' : buttonUrl} |
| 178 | style={btnInlineStyle} |
| 179 | className={aClass} |
| 180 | role={'button'} |
| 181 | aria-pressed={true} |
| 182 | target={buttonTarget ? '_blank' : null} |
| 183 | rel={relValue} |
| 184 | {...(linkToPost ? { 'data-vk-link-to-post': '1' } : {})} |
| 185 | > |
| 186 | <div className={'vk_button_link_caption'}> |
| 187 | {parse(iconBefore)} |
| 188 | {richText} |
| 189 | {parse(iconAfter)} |
| 190 | </div> |
| 191 | {/*サブキャプションが� |
| 192 | �力された時のみ表示*/} |
| 193 | {lbsubCaptionRichText ? ( |
| 194 | <p className={'vk_button_link_subCaption'}> |
| 195 | {lbsubCaptionRichText} |
| 196 | </p> |
| 197 | ) : ( |
| 198 | subCaption && ( |
| 199 | <p className={'vk_button_link_subCaption'}> |
| 200 | {subCaption} |
| 201 | </p> |
| 202 | ) |
| 203 | )} |
| 204 | </a> |
| 205 | ); |
| 206 | } |
| 207 | } |
| 208 |