diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..eb79dd5 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +node_modules +.idea diff --git a/README.md b/README.md new file mode 100644 index 0000000..4ea330b --- /dev/null +++ b/README.md @@ -0,0 +1,31 @@ +# Statamic Language (ISO 639) Dropdown Fieldtype + +![Statamic 3.0+](https://img.shields.io/badge/Statamic-3.0+-FF269E?style=for-the-badge&link=https://statamic.com) +> The simplest way to list every available langue as a selectable dropdown 🤘 + +## Features +- Displays a select field with **every ISO 639 language**. +- Set a **placeholder**. +- Allow **multiple selections**. +- Set a **maximum number of selectable items**. +- Enable **searching** through possible options. + +## Getting Started + +We have made things easy for you start. + +1. **Install the addon** + This can be achieve by downloading our latest release and configuring the package as a path repository in your `composer.json` file. + + +2. **Add the Language ISO 639 select fieldtype.** + Choose your display and hanlde values. + Customize the behavior using our various fieldtypes settings. + + +3. **Enjoy.** + +## What does your addon look like? + +![Statamic Language Selector Dropdown](https://parfaitementweb.com/statamic/statamic-language-iso639-fieldtype/fieldtype-preview.png) +![Statamic Language Selector Options](https://parfaitementweb.com/statamic/statamic-language-iso639-fieldtype/fieldtype-options.png) diff --git a/composer.json b/composer.json new file mode 100644 index 0000000..65bf4af --- /dev/null +++ b/composer.json @@ -0,0 +1,28 @@ +{ + "name": "parfaitementweb/statamic-language-iso639-fieldtype", + "description": "Language dropdown with all ISO639 options values", + "autoload": { + "psr-4": { + "Parfaitementweb\\StatamicLanguageIso639Fieldtype\\": "src" + } + }, + "authors": [ + { + "name": "Alexis Serneels" + } + ], + "support": { + "email": "addons@parfaitementweb.com" + }, + "extra": { + "statamic": { + "name": "Language Selector Fieldtype", + "description": "Language Selector Fieldtype" + }, + "laravel": { + "providers": [ + "Parfaitementweb\\StatamicLanguageIso639Fieldtype\\ServiceProvider" + ] + } + } +} diff --git a/mix-manifest.json b/mix-manifest.json new file mode 100644 index 0000000..4e9982a --- /dev/null +++ b/mix-manifest.json @@ -0,0 +1,3 @@ +{ + "/public/js/addon.js": "/public/js/addon.js" +} diff --git a/package.json b/package.json new file mode 100644 index 0000000..315be97 --- /dev/null +++ b/package.json @@ -0,0 +1,23 @@ +{ + "name": "parfaitementweb/statamic-language-iso639-fieldtype", + "description": "Statamic fieldtype to select a language (ISO 639) in a dropdown", + "scripts": { + "dev": "npm run development", + "development": "cross-env NODE_ENV=development node_modules/webpack/bin/webpack.js --progress --hide-modules --config=node_modules/laravel-mix/setup/webpack.config.js", + "watch": "npm run development -- --watch", + "watch-poll": "npm run watch -- --watch-poll", + "hot": "cross-env NODE_ENV=development node_modules/webpack-dev-server/bin/webpack-dev-server.js --inline --hot --config=node_modules/laravel-mix/setup/webpack.config.js", + "prod": "npm run production", + "production": "cross-env NODE_ENV=production node_modules/webpack/bin/webpack.js --no-progress --hide-modules --config=node_modules/laravel-mix/setup/webpack.config.js" + }, + "devDependencies": { + "autoprefixer": "^9.7.6", + "cross-env": "^5.1", + "laravel-mix": "^4.0", + "postcss-import": "^12.0.1", + "postcss-nested": "^4.2.1", + "postcss-preset-env": "^6.7.0", + "vue-template-compiler": "^2.6.12" + }, + "dependencies": {} +} diff --git a/public/js/addon.js b/public/js/addon.js new file mode 100644 index 0000000..f531507 --- /dev/null +++ b/public/js/addon.js @@ -0,0 +1 @@ +!function(e){var l={};function a(n){if(l[n])return l[n].exports;var t=l[n]={i:n,l:!1,exports:{}};return e[n].call(t.exports,t,t.exports,a),t.l=!0,t.exports}a.m=e,a.c=l,a.d=function(e,l,n){a.o(e,l)||Object.defineProperty(e,l,{enumerable:!0,get:n})},a.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},a.t=function(e,l){if(1&l&&(e=a(e)),8&l)return e;if(4&l&&"object"==typeof e&&e&&e.__esModule)return e;var n=Object.create(null);if(a.r(n),Object.defineProperty(n,"default",{enumerable:!0,value:e}),2&l&&"string"!=typeof e)for(var t in e)a.d(n,t,function(l){return e[l]}.bind(null,t));return n},a.n=function(e){var l=e&&e.__esModule?function(){return e.default}:function(){return e};return a.d(l,"a",l),l},a.o=function(e,l){return Object.prototype.hasOwnProperty.call(e,l)},a.p="/",a(a.s=0)}([function(e,l,a){e.exports=a(1)},function(e,l,a){"use strict";a.r(l);var n=function(e,l,a,n,t,u,i,o){var r,s="function"==typeof e?e.options:e;if(l&&(s.render=l,s.staticRenderFns=a,s._compiled=!0),n&&(s.functional=!0),u&&(s._scopeId="data-v-"+u),i?(r=function(e){(e=e||this.$vnode&&this.$vnode.ssrContext||this.parent&&this.parent.$vnode&&this.parent.$vnode.ssrContext)||"undefined"==typeof __VUE_SSR_CONTEXT__||(e=__VUE_SSR_CONTEXT__),t&&t.call(this,e),e&&e._registeredComponents&&e._registeredComponents.add(i)},s._ssrRegister=r):t&&(r=o?function(){t.call(this,(s.functional?this.parent:this).$root.$options.shadowRoot)}:t),r)if(s.functional){s._injectStyles=r;var v=s.render;s.render=function(e,l){return r.call(l),v(e,l)}}else{var b=s.beforeCreate;s.beforeCreate=b?[].concat(b,r):[r]}return{exports:e,options:s}}({mixins:[Fieldtype,{methods:{normalizeInputOptions:function(e){return _.map(e,(function(l,a){return{value:Array.isArray(e)?l:a,label:l||a}}))}}}],data:function(){return{options:[{label:"Afar",value:"aa"},{label:"Abkhazian",value:"ab"},{label:"Avestan",value:"ae"},{label:"Afrikaans",value:"af"},{label:"Akan",value:"ak"},{label:"Amharic",value:"am"},{label:"Aragonese",value:"an"},{label:"Arabic",value:"ar"},{label:"Assamese",value:"as"},{label:"Avaric",value:"av"},{label:"Aymara",value:"ay"},{label:"Azerbaijani",value:"az"},{label:"Bashkir",value:"ba"},{label:"Belarusian",value:"be"},{label:"Bulgarian",value:"bg"},{label:"Bihari languages",value:"bh"},{label:"Bislama",value:"bi"},{label:"Bambara",value:"bm"},{label:"Bengali",value:"bn"},{label:"Tibetan",value:"bo"},{label:"Breton",value:"br"},{label:"Bosnian",value:"bs"},{label:"Catalan; Valencian",value:"ca"},{label:"Chechen",value:"ce"},{label:"Chamorro",value:"ch"},{label:"Corsican",value:"co"},{label:"Cree",value:"cr"},{label:"Czech",value:"cs"},{label:"Church Slavic; Old Slavonic; Church Slavonic; Old Bulgarian; Old Church Slavonic",value:"cu"},{label:"Chuvash",value:"cv"},{label:"Welsh",value:"cy"},{label:"Danish",value:"da"},{label:"German",value:"de"},{label:"Divehi; Dhivehi; Maldivian",value:"dv"},{label:"Dzongkha",value:"dz"},{label:"Ewe",value:"ee"},{label:"Greek, Modern (1453-)",value:"el"},{label:"English",value:"en"},{label:"Esperanto",value:"eo"},{label:"Spanish; Castilian",value:"es"},{label:"Estonian",value:"et"},{label:"Basque",value:"eu"},{label:"Persian",value:"fa"},{label:"Fulah",value:"ff"},{label:"Finnish",value:"fi"},{label:"Fijian",value:"fj"},{label:"Faroese",value:"fo"},{label:"French",value:"fr"},{label:"Western Frisian",value:"fy"},{label:"Irish",value:"ga"},{label:"Gaelic; Scottish Gaelic",value:"gd"},{label:"Galician",value:"gl"},{label:"Guarani",value:"gn"},{label:"Gujarati",value:"gu"},{label:"Manx",value:"gv"},{label:"Hausa",value:"ha"},{label:"Hebrew",value:"he"},{label:"Hindi",value:"hi"},{label:"Hiri Motu",value:"ho"},{label:"Croatian",value:"hr"},{label:"Haitian; Haitian Creole",value:"ht"},{label:"Hungarian",value:"hu"},{label:"Armenian",value:"hy"},{label:"Herero",value:"hz"},{label:"Interlingua (International Auxiliary Language Association)",value:"ia"},{label:"Indonesian",value:"id"},{label:"Interlingue; Occidental",value:"ie"},{label:"Igbo",value:"ig"},{label:"Sichuan Yi; Nuosu",value:"ii"},{label:"Inupiaq",value:"ik"},{label:"Ido",value:"io"},{label:"Icelandic",value:"is"},{label:"Italian",value:"it"},{label:"Inuktitut",value:"iu"},{label:"Japanese",value:"ja"},{label:"Javanese",value:"jv"},{label:"Georgian",value:"ka"},{label:"Kongo",value:"kg"},{label:"Kikuyu; Gikuyu",value:"ki"},{label:"Kuanyama; Kwanyama",value:"kj"},{label:"Kazakh",value:"kk"},{label:"Kalaallisut; Greenlandic",value:"kl"},{label:"Central Khmer",value:"km"},{label:"Kannada",value:"kn"},{label:"Korean",value:"ko"},{label:"Kanuri",value:"kr"},{label:"Kashmiri",value:"ks"},{label:"Kurdish",value:"ku"},{label:"Komi",value:"kv"},{label:"Cornish",value:"kw"},{label:"Kirghiz; Kyrgyz",value:"ky"},{label:"Latin",value:"la"},{label:"Luxembourgish; Letzeburgesch",value:"lb"},{label:"Ganda",value:"lg"},{label:"Limburgan; Limburger; Limburgish",value:"li"},{label:"Lingala",value:"ln"},{label:"Lao",value:"lo"},{label:"Lithuanian",value:"lt"},{label:"Luba-Katanga",value:"lu"},{label:"Latvian",value:"lv"},{label:"Malagasy",value:"mg"},{label:"Marshallese",value:"mh"},{label:"Maori",value:"mi"},{label:"Macedonian",value:"mk"},{label:"Malayalam",value:"ml"},{label:"Mongolian",value:"mn"},{label:"Marathi",value:"mr"},{label:"Malay",value:"ms"},{label:"Maltese",value:"mt"},{label:"Burmese",value:"my"},{label:"Nauru",value:"na"},{label:"Bokmål, Norwegian; Norwegian Bokmål",value:"nb"},{label:"Ndebele, North; North Ndebele",value:"nd"},{label:"Nepali",value:"ne"},{label:"Ndonga",value:"ng"},{label:"Dutch; Flemish",value:"nl"},{label:"Norwegian Nynorsk; Nynorsk, Norwegian",value:"nn"},{label:"Norwegian",value:"no"},{label:"Ndebele, South; South Ndebele",value:"nr"},{label:"Navajo; Navaho",value:"nv"},{label:"Chichewa; Chewa; Nyanja",value:"ny"},{label:"Occitan (post 1500)",value:"oc"},{label:"Ojibwa",value:"oj"},{label:"Oromo",value:"om"},{label:"Oriya",value:"or"},{label:"Ossetian; Ossetic",value:"os"},{label:"Panjabi; Punjabi",value:"pa"},{label:"Pali",value:"pi"},{label:"Polish",value:"pl"},{label:"Pushto; Pashto",value:"ps"},{label:"Portuguese",value:"pt"},{label:"Quechua",value:"qu"},{label:"Romansh",value:"rm"},{label:"Rundi",value:"rn"},{label:"Romanian; Moldavian; Moldovan",value:"ro"},{label:"Russian",value:"ru"},{label:"Kinyarwanda",value:"rw"},{label:"Sanskrit",value:"sa"},{label:"Sardinian",value:"sc"},{label:"Sindhi",value:"sd"},{label:"Northern Sami",value:"se"},{label:"Sango",value:"sg"},{label:"Sinhala; Sinhalese",value:"si"},{label:"Slovak",value:"sk"},{label:"Slovenian",value:"sl"},{label:"Samoan",value:"sm"},{label:"Shona",value:"sn"},{label:"Somali",value:"so"},{label:"Albanian",value:"sq"},{label:"Serbian",value:"sr"},{label:"Swati",value:"ss"},{label:"Sotho, Southern",value:"st"},{label:"Sundanese",value:"su"},{label:"Swedish",value:"sv"},{label:"Swahili",value:"sw"},{label:"Tamil",value:"ta"},{label:"Telugu",value:"te"},{label:"Tajik",value:"tg"},{label:"Thai",value:"th"},{label:"Tigrinya",value:"ti"},{label:"Turkmen",value:"tk"},{label:"Tagalog",value:"tl"},{label:"Tswana",value:"tn"},{label:"Tonga (Tonga Islands)",value:"to"},{label:"Turkish",value:"tr"},{label:"Tsonga",value:"ts"},{label:"Tatar",value:"tt"},{label:"Twi",value:"tw"},{label:"Tahitian",value:"ty"},{label:"Uighur; Uyghur",value:"ug"},{label:"Ukrainian",value:"uk"},{label:"Urdu",value:"ur"},{label:"Uzbek",value:"uz"},{label:"Venda",value:"ve"},{label:"Vietnamese",value:"vi"},{label:"Volapük",value:"vo"},{label:"Walloon",value:"wa"},{label:"Wolof",value:"wo"},{label:"Xhosa",value:"xh"},{label:"Yiddish",value:"yi"},{label:"Yoruba",value:"yo"},{label:"Zhuang; Chuang",value:"za"},{label:"Chinese",value:"zh"},{label:"Zulu",value:"zu"}]}},computed:{selectedOptions:function(){var e=this,l=this.value||[];return"string"!=typeof l&&"number"!=typeof l||(l=[l]),l.map((function(l){return _.findWhere(e.options,{value:l})||{value:l,label:l}}))},options:function(){return this.normalizeInputOptions(this.config.options)},replicatorPreview:function(){return this.selectedOptions.map((function(e){return e.label})).join(", ")},resetOnOptionsChange:function(){return!0===this.config.reset_on_options_change&&function(e,l,a){var n=e.map((function(e){return e.value}));return!a.some((function(e){return n.includes(e.value)}))}},limitReached:function(){return!!this.config.max_items&&this.currentLength>=this.config.max_items},limitExceeded:function(){return!!this.config.max_items&&this.currentLength>this.config.max_items},currentLength:function(){return this.value?"string"==typeof this.value?1:this.value.length:0},limitIndicatorColor:function(){return this.limitExceeded?"text-red":this.limitReached?"text-green":"text-grey"}},methods:{focus:function(){this.$refs.input.focus()},vueSelectUpdated:function(e){this.config.multiple?this.update(e.map((function(e){return e.value}))):e?this.update(e.value):this.update(null)}}},(function(){var e=this,l=e.$createElement,a=e._self._c||l;return a("div",{staticClass:"flex"},[a("v-select",{ref:"input",staticClass:"flex-1",attrs:{name:e.name,clearable:e.config.clearable,disabled:e.config.disabled||e.isReadOnly||e.config.multiple&&e.limitReached,options:e.options,placeholder:e.config.placeholder,searchable:e.config.searchable||e.config.taggable,taggable:e.config.taggable,"push-tags":e.config.push_tags,multiple:e.config.multiple,"reset-on-options-change":e.resetOnOptionsChange,"close-on-select":!0,value:e.selectedOptions,"create-option":function(e){return{value:e,label:e}}},on:{input:e.vueSelectUpdated,"search:focus":function(l){return e.$emit("focus")},"search:blur":function(l){return e.$emit("blur")}},scopedSlots:e._u([e.config.multiple?{key:"selected-option-container",fn:function(){return[a("i",{staticClass:"hidden"})]},proxy:!0}:null,e.config.multiple?{key:"search",fn:function(l){var n=l.events,t=l.attributes;return[a("input",e._g(e._b({staticClass:"vs__search",attrs:{placeholder:e.config.placeholder,type:"search"}},"input",t,!1),n))]}}:null,{key:"no-options",fn:function(){return[a("div",{staticClass:"text-sm text-grey-70 text-left py-1 px-2",domProps:{textContent:e._s(e.__("No options to choose from."))}})]},proxy:!0},e.config.multiple?{key:"footer",fn:function(l){var n=l.deselect;return[a("div",{staticClass:"vs__selected-options-outside flex flex-wrap"},e._l(e.selectedOptions,(function(l){return a("span",{key:l.value,staticClass:"vs__selected mt-1"},[e._v("\n "+e._s(l.label)+"\n "),e.readOnly?a("button",{staticClass:"vs__deselect",attrs:{type:"button"}},[a("span",{staticClass:"opacity-50"},[e._v("×")])]):a("button",{staticClass:"vs__deselect",attrs:{type:"button","aria-label":e.__("Deselect option")},on:{click:function(e){return n(l)}}},[a("span",[e._v("×")])])])})),0)]}}:null],null,!0)}),e._v(" "),e.config.max_items?a("div",{staticClass:"text-xs ml-1 mt-1.5",class:e.limitIndicatorColor},[a("span",{domProps:{textContent:e._s(e.currentLength)}}),e._v("/"),a("span",{domProps:{textContent:e._s(e.config.max_items)}})]):e._e()],1)}),[],!1,null,null,null).exports;Statamic.booting((function(){Statamic.$components.register("language_selector-fieldtype",n)}))}]); \ No newline at end of file diff --git a/src/Fieldtypes/LanguageSelector.php b/src/Fieldtypes/LanguageSelector.php new file mode 100644 index 0000000..bb784c6 --- /dev/null +++ b/src/Fieldtypes/LanguageSelector.php @@ -0,0 +1,52 @@ + [ + 'display' => __('Placeholder'), + 'instructions' => __('statamic::fieldtypes.select.config.placeholder'), + 'type' => 'text', + 'default' => '', + 'width' => 50, + ], + 'multiple' => [ + 'display' => __('Multiple'), + 'instructions' => __('statamic::fieldtypes.select.config.multiple'), + 'type' => 'toggle', + 'default' => false, + 'width' => 50, + ], + 'max_items' => [ + 'display' => __('Max Items'), + 'instructions' => __('statamic::messages.max_items_instructions'), + 'type' => 'integer', + 'width' => 50, + ], + 'searchable' => [ + 'display' => __('Searchable'), + 'instructions' => __('statamic::fieldtypes.select.config.searchable'), + 'type' => 'toggle', + 'default' => true, + 'width' => 50, + ] + ]; + } +} diff --git a/src/ServiceProvider.php b/src/ServiceProvider.php new file mode 100644 index 0000000..68dc101 --- /dev/null +++ b/src/ServiceProvider.php @@ -0,0 +1,18 @@ + { + Statamic.$components.register('language_selector-fieldtype', LanguageSelector); +}); diff --git a/src/resources/js/components/fieldtypes/LanguageSelector.vue b/src/resources/js/components/fieldtypes/LanguageSelector.vue new file mode 100644 index 0000000..1a6e485 --- /dev/null +++ b/src/resources/js/components/fieldtypes/LanguageSelector.vue @@ -0,0 +1,334 @@ + + + + diff --git a/webpack.mix.js b/webpack.mix.js new file mode 100644 index 0000000..b38af16 --- /dev/null +++ b/webpack.mix.js @@ -0,0 +1,14 @@ +let mix = require('laravel-mix'); + +/* + |-------------------------------------------------------------------------- + | Mix Asset Management + |-------------------------------------------------------------------------- + | + | Mix provides a clean, fluent API for defining some Webpack build steps + | for your Laravel application. By default, we are compiling the Sass + | file for the application as well as bundling up all the JS files. + | + */ + +mix.js('src/resources/js/addon.js', 'public/js/addon.js');