├── .gitignore ├── README.md ├── after.png ├── before.png ├── composer.json ├── dist ├── css │ └── field.css └── js │ └── field.js ├── mix-manifest.json ├── package.json ├── resources ├── js │ ├── components │ │ └── IndexField.vue │ └── field.js └── sass │ └── field.scss ├── src ├── FieldServiceProvider.php └── TextWrap.php └── webpack.mix.js /.gitignore: -------------------------------------------------------------------------------- 1 | /.idea 2 | /vendor 3 | /node_modules 4 | package-lock.json 5 | composer.phar 6 | composer.lock 7 | phpunit.xml 8 | .phpunit.result.cache 9 | .DS_Store 10 | Thumbs.db 11 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Nova Text Field With Wrap Options 2 | 3 | **Since Nova now includes `asHtml()` Meta on the Text field (as of [v1.0.9](https://github.com/laravel/nova-issues/issues/280)), there is no more need for this package as same functionality can be achieved with core Text field.** 4 | 5 | The default text field in nova doesn't wrap, this causes table to become very wide. By using this field you can either wrap after set number of characters or by splitting the text by a specified marker. 6 | 7 | ## Screenshots 8 | 9 | **How it looks with regular text field:** 10 | ![screenshot how it looks with regular text field ](before.png?raw=true "with regular text field") 11 | 12 | **How it looks with text wrap field:** 13 | ![screenshot how it looks with text wrap field ](after.png?raw=true "with text wrap field") 14 | 15 | ## Installation 16 | 17 | Install the package into a Laravel app that uses [Nova](https://nova.laravel.com) with Composer: 18 | 19 | ```bash 20 | composer require treestoneit/text-wrap 21 | ``` 22 | 23 | ## Usage 24 | 25 | Add the field to your resource in the ```fields``` method: 26 | 27 | ```php 28 | use Treestoneit\TextWrap\TextWrap; 29 | ... 30 | ... 31 | TextWrap::make('Product Name')->wrapMethod('length',40), 32 | ``` 33 | 34 | If you would like to use the wrap through spliting the text by marker, here is an example: 35 | 36 | ```php 37 | use Treestoneit\TextWrap\TextWrap; 38 | ... 39 | ... 40 | TextWrap::make('Product Name')->wrapMethod('explode','-*-'), 41 | ``` 42 | 43 | Please note: _Only Index version of the field is configured to wrap_ 44 | -------------------------------------------------------------------------------- /after.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/treeStoneIT/text-wrap/41e4ca40ea4a3848c09f529e1bac0947d41cc7dc/after.png -------------------------------------------------------------------------------- /before.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/treeStoneIT/text-wrap/41e4ca40ea4a3848c09f529e1bac0947d41cc7dc/before.png -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "treestoneit/text-wrap", 3 | "description": "A Laravel Nova Wrapped Text field.", 4 | "keywords": [ 5 | "laravel", 6 | "nova" 7 | ], 8 | "license": "MIT", 9 | "require": { 10 | "php": ">=7.1.0" 11 | }, 12 | "autoload": { 13 | "psr-4": { 14 | "Treestoneit\\TextWrap\\": "src/" 15 | } 16 | }, 17 | "extra": { 18 | "laravel": { 19 | "providers": [ 20 | "Treestoneit\\TextWrap\\FieldServiceProvider" 21 | ] 22 | } 23 | }, 24 | "config": { 25 | "sort-packages": true 26 | }, 27 | "minimum-stability": "dev", 28 | "prefer-stable": true 29 | } 30 | -------------------------------------------------------------------------------- /dist/css/field.css: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/treeStoneIT/text-wrap/41e4ca40ea4a3848c09f529e1bac0947d41cc7dc/dist/css/field.css -------------------------------------------------------------------------------- /dist/js/field.js: -------------------------------------------------------------------------------- 1 | !function(e){var t={};function n(r){if(t[r])return t[r].exports;var o=t[r]={i:r,l:!1,exports:{}};return e[r].call(o.exports,o,o.exports,n),o.l=!0,o.exports}n.m=e,n.c=t,n.d=function(e,t,r){n.o(e,t)||Object.defineProperty(e,t,{configurable:!1,enumerable:!0,get:r})},n.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="",n(n.s=0)}([function(e,t,n){n(1),e.exports=n(6)},function(e,t,n){Nova.booting(function(e,t){e.component("index-text-wrap",n(2))})},function(e,t,n){var r=n(3)(n(4),n(5),!1,null,null,null);e.exports=r.exports},function(e,t){e.exports=function(e,t,n,r,o,i){var s,u=e=e||{},c=typeof e.default;"object"!==c&&"function"!==c||(s=e,u=e.default);var a,p="function"==typeof u?u.options:u;if(t&&(p.render=t.render,p.staticRenderFns=t.staticRenderFns,p._compiled=!0),n&&(p.functional=!0),o&&(p._scopeId=o),i?(a=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__),r&&r.call(this,e),e&&e._registeredComponents&&e._registeredComponents.add(i)},p._ssrRegister=a):r&&(a=r),a){var f=p.functional,l=f?p.render:p.beforeCreate;f?(p._injectStyles=a,p.render=function(e,t){return a.call(t),l(e,t)}):p.beforeCreate=l?[].concat(l,a):[a]}return{esModule:s,exports:u,options:p}}},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.default={props:["resourceName","field"],methods:{wrapText:function(e){var t=e.value,n=e.wrap.marker,r=e.wrap.method,o="";return"length"===r?o=this.wordwrap(t,n):"explode"===r&&(o=this.explodeAndJoin(t,n)),o},explodeAndJoin:function(e,t){return e.split(t).join("
")},wordwrap:function(e,t){var n=[],r=[],o=0;return e.split(" ").forEach(function(e){o+e.length>=t&&(n.push(r.join(" ")),r=[],o=0),o+=e.length+1,r.push(e)}),r.length>0&&n.push(r.join(" ")),n.join("
")}}}},function(e,t){e.exports={render:function(){var e=this.$createElement;return(this._self._c||e)("p",{staticClass:"whitespace-no-wrap",domProps:{innerHTML:this._s(this.wrapText(this.field))}})},staticRenderFns:[]}},function(e,t){}]); -------------------------------------------------------------------------------- /mix-manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "/dist/js/field.js": "/dist/js/field.js", 3 | "/dist/css/field.css": "/dist/css/field.css" 4 | } -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "private": true, 3 | "scripts": { 4 | "dev": "npm run development", 5 | "development": "cross-env NODE_ENV=development node_modules/webpack/bin/webpack.js --progress --hide-modules --config=node_modules/laravel-mix/setup/webpack.config.js", 6 | "watch": "cross-env NODE_ENV=development node_modules/webpack/bin/webpack.js --watch --progress --hide-modules --config=node_modules/laravel-mix/setup/webpack.config.js", 7 | "watch-poll": "npm run watch -- --watch-poll", 8 | "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", 9 | "prod": "npm run production", 10 | "production": "cross-env NODE_ENV=production node_modules/webpack/bin/webpack.js --progress --hide-modules --config=node_modules/laravel-mix/setup/webpack.config.js" 11 | }, 12 | "devDependencies": { 13 | "cross-env": "^5.0.0", 14 | "laravel-mix": "^1.0", 15 | "laravel-nova": "^1.0" 16 | }, 17 | "dependencies": { 18 | "vue": "^2.5.0" 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /resources/js/components/IndexField.vue: -------------------------------------------------------------------------------- 1 | 4 | 5 | -------------------------------------------------------------------------------- /resources/js/field.js: -------------------------------------------------------------------------------- 1 | Nova.booting((Vue, router) => { 2 | Vue.component('index-text-wrap', require('./components/IndexField')); 3 | }) 4 | -------------------------------------------------------------------------------- /resources/sass/field.scss: -------------------------------------------------------------------------------- 1 | // Nova Tool CSS 2 | -------------------------------------------------------------------------------- /src/FieldServiceProvider.php: -------------------------------------------------------------------------------- 1 | $wrapMethod, 41 | 'marker' => $wrapMarker, 42 | ]; 43 | return $this->withMeta(['wrap' => $wrapMeta]); 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /webpack.mix.js: -------------------------------------------------------------------------------- 1 | let mix = require('laravel-mix') 2 | 3 | mix.js('resources/js/field.js', 'dist/js') 4 | .sass('resources/sass/field.scss', 'dist/css') 5 | .webpackConfig({ 6 | resolve: { 7 | symlinks: false 8 | } 9 | }) 10 | --------------------------------------------------------------------------------